[lcrash] ADD: Crash screen on VGA

This commit is contained in:
xwashere 2024-04-30 10:27:21 -04:00
parent dd850450cc
commit cd96c1d220
Signed by: XWasHere
GPG Key ID: 042F8BFA1B0EF93B
20 changed files with 1793 additions and 17 deletions

View File

@ -8,7 +8,7 @@ lw_project(lcrash
enable_language(ASM) enable_language(ASM)
lw_add_executable(lcrashkern lw_add_executable(lcrashkern
SOURCES main.c cmdline.c util.c lnxboot.c math.c debug/debug.c acpi/acpi.c efi/efi.c efi/guid.c efi/memmap.c gdb/gdb.c pci/pci.c mm/phys.c mm/kmalloc.c mm/virt.c driver/sysbus.c SOURCES main.c cmdline.c util.c lnxboot.c math.c irq.c irq.s debug/debug.c acpi/acpi.c efi/efi.c efi/guid.c efi/memmap.c gdb/gdb.c pci/pci.c mm/phys.c mm/kmalloc.c mm/virt.c driver/sysbus.c driver/vga.c driver/cap/textdisplay.c
) )
add_executable(lcrashkernld IMPORTED) add_executable(lcrashkernld IMPORTED)
set_property(TARGET lcrashkernld PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld) set_property(TARGET lcrashkernld PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld)

View File

@ -0,0 +1,17 @@
#include <lcrash/driver/sysbus.h>
struct SysbusDeviceCapability* TextModeDisplayCapability = 0;
bool TextModeDisplayCapabilityInitialized = false;
bool TextModeDisplayCapabilityIsInitialized() {
return TextModeDisplayCapabilityInitialized;
}
void TextModeDisplayCapabilityInitialize() {
TextModeDisplayCapability = SysbusCreateCapability();
TextModeDisplayCapabilityInitialized = true;
};
struct SysbusDeviceCapability* TextModeDisplayCapabilityGetCapability() {
return TextModeDisplayCapability;
}

View File

@ -0,0 +1,62 @@
#pragma once
#include <lcrash/types.h>
#include <lcrash/driver/sysbus.h>
/**
* Text-mode display capability.
*/
struct TextModeDisplayCapability {
/**
* Switch the display into text mode if it supports
* other display modes
*
* \return 0 on success
*/
s32 (*Enable)(struct SysbusDevice* Device);
/**
* Clear the screen and reset it's attributes to a known
* state, what state exactly? That's for me to know and
* you to find out.
*
* \return 0 on success
*/
s32 (*Reset)(struct SysbusDevice* Device);
/**
* Get the maximum number of usable colors
*
* \return color count or -ERROR
*/
s32 (*GetPaletteSize)(struct SysbusDevice* Device);
/**
* Set a palette color
*
* \return 0 on success
*/
s32 (*SetPaletteColor)(struct SysbusDevice* Device, u32 ID, u8 Red, u8 Green, u8 Blue);
/**
* Set a character on the display
*
* \return 0 on success
*/
s32 (*SetCharacter)(struct SysbusDevice* Device, u32 Row, u32 Col, c8 Char, u32 ForegroundColor, u32 BackgroundColor);
};
/**
* Initialize the capability driver
*/
void TextModeDisplayCapabilityInitialize();
/**
* Function name
*/
struct SysbusDeviceCapability* TextModeDisplayCapabilityGetCapability();
/**
* Yeah
*/
bool TextModeDisplayCapabilityIsInitialized();

View File

@ -86,6 +86,9 @@ struct SysbusDevice* SysbusCreateDeviceInternal(
// Add us as an instance // Add us as an instance
Description->Instances[Description->InstanceCount++] = Device; Description->Instances[Description->InstanceCount++] = Device;
// Run hook
if (Description->CreateDevice != 0) Description->CreateDevice(Device, DeviceData);
return Device; return Device;
} }
@ -109,6 +112,22 @@ void SysbusDeleteDevice(struct SysbusDevice* Device) {
Panic("todo"); Panic("todo");
} }
struct SysbusDeviceCapability* SysbusCreateCapability() {
struct SysbusDeviceCapability* Capability = KernelHeapAlloc(sizeof(struct SysbusDeviceCapability), 1, 0);
return Capability;
}
void SysbusDeleteCapability() {
Panic("todo");
}
void* SysbusGetCapability(struct SysbusDevice* Device, struct SysbusDeviceCapability* Capability) {
if (Device->DeviceDescription->GetCapability != 0) {
return Device->DeviceDescription->GetCapability(Device, Capability);
} else return 0;
}
void SysbusInitialize() { void SysbusInitialize() {
// Create the sysbus root // Create the sysbus root
SysbusRootDeviceDescription = SysbusCreateDeviceDescriptionInternal(); SysbusRootDeviceDescription = SysbusCreateDeviceDescriptionInternal();
@ -124,3 +143,5 @@ void SysbusInitialize() {
return; return;
} }
struct SysbusDevice* SysbusGetRootDevice() { return SysbusRootDevice; }

View File

@ -184,3 +184,23 @@ struct SysbusDevice* SysbusCreateDevice(
* Delete a device * Delete a device
*/ */
void SysbusDeleteDevice(struct SysbusDevice* Device); void SysbusDeleteDevice(struct SysbusDevice* Device);
/**
* Create a sysbus capability
*/
struct SysbusDeviceCapability* SysbusCreateCapability();
/**
* Delete a sysbus capability
*/
void SysbusDeleteCapability();
/**
* Get a sysbus capability
*/
void* SysbusGetCapability(struct SysbusDevice* Device, struct SysbusDeviceCapability* Capability);
/**
* Get the system bus device
*/
struct SysbusDevice* SysbusGetRootDevice();

913
lcrash/driver/vga.c Normal file
View File

@ -0,0 +1,913 @@
#include <lcrash/driver/vga.h>
#include <lcrash/driver/cap/textdisplay.h>
#include <lcrash/util.h>
#include <lcrash/mm/kmalloc.h>
#define _(X, Y, A, B, C, D, E, F, G, H) \
[X][Y] = A, [X + 1][Y] = B, [X + 2][Y] = C, [X + 3][Y] = D, [X + 4][Y] = E, [X + 5][Y] = F, [X + 6][Y] = G, [X + 7][Y] = H,
// Font uh yeah its a font yeah B)
u8 VgaFont[256][32] = {
_(0x00, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x00, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x00, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x00, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x00, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x00, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x00, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x00, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x00, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x00, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x00, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x00, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x00, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x00, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x00, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x00, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x08, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x08, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x08, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x08, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x08, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x08, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x08, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x08, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x08, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x08, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x08, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x08, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x08, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x08, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x08, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x08, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x10, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x10, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x10, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x10, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x10, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x10, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x10, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x10, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x10, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x10, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x10, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x10, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x10, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x10, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x10, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x10, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x18, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x18, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x18, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x18, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x18, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x18, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x18, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x18, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x18, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x18, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x18, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x18, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x18, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x18, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x18, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x18, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x20, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x20, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x20, 0x2, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x20, 0x3, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x20, 0x4, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x20, 0x5, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x20, 0x6, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x20, 0x7, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x20, 0x8, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x20, 0x9, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x20, 0xa, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x20, 0xb, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x20, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x20, 0xd, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x20, 0xe, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x20, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x28, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x28, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x28, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00001100)
_(0x28, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00001100)
_(0x28, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00001100)
_(0x28, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00001100)
_(0x28, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00001100)
_(0x28, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00110000)
_(0x28, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00110000)
_(0x28, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00110000)
_(0x28, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00110000)
_(0x28, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b11000000)
_(0x28, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b11000000)
_(0x28, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b11000000)
_(0x28, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b01100000, 0b00000000, 0b01100000, 0b11000000)
_(0x28, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b01100000, 0b00000000, 0b01100000, 0b11000000)
_(0x30, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x30, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x30, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x30, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x30, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x30, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x30, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x30, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x30, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x30, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x30, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x30, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x30, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x30, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x30, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x30, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x38, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x38, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x38, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x38, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x38, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x38, 0x5, 0b00000000, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x38, 0x6, 0b00000000, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x38, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x38, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x38, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x38, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x38, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x38, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x38, 0xd, 0b00000000, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x38, 0xe, 0b00000000, 0b00000000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x38, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x40, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x40, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x40, 0x2, 0b00000000, 0b00110000, 0b11111000, 0b11111100, 0b11111000, 0b11111100, 0b11111100, 0b01111100)
_(0x40, 0x3, 0b00000000, 0b01111000, 0b11111000, 0b11111100, 0b11111100, 0b11111100, 0b11111100, 0b11111100)
_(0x40, 0x4, 0b00000000, 0b11001100, 0b11001100, 0b11000000, 0b11001100, 0b11000000, 0b11000000, 0b11000000)
_(0x40, 0x5, 0b00000000, 0b11001100, 0b11001100, 0b11000000, 0b11001100, 0b11000000, 0b11000000, 0b11000000)
_(0x40, 0x6, 0b00000000, 0b11001100, 0b11001100, 0b11000000, 0b11001100, 0b11000000, 0b11000000, 0b11000000)
_(0x40, 0x7, 0b00000000, 0b11001100, 0b11001100, 0b11000000, 0b11001100, 0b11000000, 0b11000000, 0b11000000)
_(0x40, 0x8, 0b00000000, 0b11001100, 0b11001100, 0b11000000, 0b11001100, 0b11000000, 0b11000000, 0b11000000)
_(0x40, 0x9, 0b00000000, 0b11111100, 0b11111000, 0b11000000, 0b11001100, 0b11111100, 0b11111100, 0b11011100)
_(0x40, 0xa, 0b00000000, 0b11111100, 0b11111000, 0b11000000, 0b11001100, 0b11111100, 0b11111100, 0b11011100)
_(0x40, 0xb, 0b00000000, 0b11001100, 0b11001100, 0b11000000, 0b11001100, 0b11000000, 0b11000000, 0b11001100)
_(0x40, 0xc, 0b00000000, 0b11001100, 0b11001100, 0b11000000, 0b11001100, 0b11000000, 0b11000000, 0b11001100)
_(0x40, 0xd, 0b00000000, 0b11001100, 0b11001100, 0b11000000, 0b11001100, 0b11000000, 0b11000000, 0b11001100)
_(0x40, 0xe, 0b00000000, 0b11001100, 0b11111100, 0b11111100, 0b11111100, 0b11111100, 0b11000000, 0b11111100)
_(0x40, 0xf, 0b00000000, 0b11001100, 0b11111000, 0b11111100, 0b11111000, 0b11111100, 0b11000000, 0b01111000)
_(0x48, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x48, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x48, 0x2, 0b11001100, 0b11111100, 0b00001100, 0b11001100, 0b11000000, 0b11000110, 0b11000110, 0b11111100)
_(0x48, 0x3, 0b11001100, 0b11111100, 0b00001100, 0b11001100, 0b11000000, 0b11000110, 0b11000110, 0b11111100)
_(0x48, 0x4, 0b11001100, 0b00110000, 0b00001100, 0b11001100, 0b11000000, 0b11101110, 0b11000110, 0b11001100)
_(0x48, 0x5, 0b11001100, 0b00110000, 0b00001100, 0b11011000, 0b11000000, 0b11101110, 0b11000110, 0b11001100)
_(0x48, 0x6, 0b11001100, 0b00110000, 0b00001100, 0b11011000, 0b11000000, 0b11111110, 0b11000110, 0b11001100)
_(0x48, 0x7, 0b11001100, 0b00110000, 0b00001100, 0b11011000, 0b11000000, 0b11010110, 0b11110110, 0b11001100)
_(0x48, 0x8, 0b11001100, 0b00110000, 0b00001100, 0b11100000, 0b11000000, 0b11010110, 0b11110110, 0b11001100)
_(0x48, 0x9, 0b11111100, 0b00110000, 0b00001100, 0b11110000, 0b11000000, 0b11000110, 0b11110110, 0b11001100)
_(0x48, 0xa, 0b11111100, 0b00110000, 0b00001100, 0b11011000, 0b11000000, 0b11000110, 0b11011110, 0b11001100)
_(0x48, 0xb, 0b11001100, 0b00110000, 0b00001100, 0b11011000, 0b11000000, 0b11000110, 0b11011110, 0b11001100)
_(0x48, 0xc, 0b11001100, 0b00110000, 0b11001100, 0b11011000, 0b11000000, 0b11000110, 0b11011110, 0b11001100)
_(0x48, 0xd, 0b11001100, 0b00110000, 0b11001100, 0b11001100, 0b11000000, 0b11000110, 0b11001110, 0b11001100)
_(0x48, 0xe, 0b11001100, 0b11111100, 0b11111100, 0b11001100, 0b11111100, 0b11000110, 0b11001110, 0b11111100)
_(0x48, 0xf, 0b11001100, 0b11111100, 0b01111000, 0b11001100, 0b01111100, 0b11000110, 0b11001110, 0b11111100)
_(0x50, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x50, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x50, 0x2, 0b11111100, 0b01111000, 0b11111000, 0b01111000, 0b11111100, 0b11001100, 0b11001100, 0b11000110)
_(0x50, 0x3, 0b11111100, 0b11111100, 0b11001100, 0b11111100, 0b11111100, 0b11001100, 0b11001100, 0b11000110)
_(0x50, 0x4, 0b11001100, 0b11001100, 0b11001100, 0b11000000, 0b00110000, 0b11001100, 0b11001100, 0b11000110)
_(0x50, 0x5, 0b11001100, 0b11001100, 0b11001100, 0b11000000, 0b00110000, 0b11001100, 0b11001100, 0b11000110)
_(0x50, 0x6, 0b11001100, 0b11001100, 0b11001100, 0b11000000, 0b00110000, 0b11001100, 0b11001100, 0b11000110)
_(0x50, 0x7, 0b11001100, 0b11001100, 0b11001100, 0b11000000, 0b00110000, 0b11001100, 0b01001000, 0b11000110)
_(0x50, 0x8, 0b11001100, 0b11001100, 0b11001100, 0b11111000, 0b00110000, 0b11001100, 0b01001000, 0b11000110)
_(0x50, 0x9, 0b11111100, 0b11001100, 0b11111100, 0b01111100, 0b00110000, 0b11001100, 0b01001000, 0b11000110)
_(0x50, 0xa, 0b11111100, 0b11001100, 0b11111000, 0b00001100, 0b00110000, 0b11001100, 0b01111000, 0b11000110)
_(0x50, 0xb, 0b11000000, 0b11101100, 0b11011000, 0b00001100, 0b00110000, 0b11001100, 0b01111000, 0b11010110)
_(0x50, 0xc, 0b11000000, 0b11111100, 0b11011000, 0b00001100, 0b00110000, 0b11001100, 0b00110000, 0b11010110)
_(0x50, 0xd, 0b11000000, 0b01111000, 0b11001100, 0b00001100, 0b00110000, 0b11001100, 0b00110000, 0b11010110)
_(0x50, 0xe, 0b11000000, 0b00011100, 0b11001100, 0b11111100, 0b00110000, 0b11111100, 0b00110000, 0b11111110)
_(0x50, 0xf, 0b11000000, 0b00001100, 0b11001100, 0b01111000, 0b00110000, 0b11111100, 0b00110000, 0b01101100)
_(0x58, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x58, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x58, 0x2, 0b11001100, 0b11001100, 0b11111100, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x58, 0x3, 0b11001100, 0b11001100, 0b11111100, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x58, 0x4, 0b11001100, 0b11001100, 0b00001100, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x58, 0x5, 0b01111000, 0b11001100, 0b00001100, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x58, 0x6, 0b01111000, 0b01111000, 0b00011000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x58, 0x7, 0b01111000, 0b01111000, 0b00011000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x58, 0x8, 0b00110000, 0b01111000, 0b00011000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x58, 0x9, 0b00110000, 0b01111000, 0b00110000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x58, 0xa, 0b01111000, 0b00110000, 0b00110000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x58, 0xb, 0b01111000, 0b00110000, 0b00110000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x58, 0xc, 0b01111000, 0b00110000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x58, 0xd, 0b11001100, 0b00110000, 0b01100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x58, 0xe, 0b11001100, 0b00110000, 0b11111100, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x58, 0xf, 0b11001100, 0b00110000, 0b11111100, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x60, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x60, 0x1, 0b11100000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x60, 0x2, 0b11110000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x60, 0x3, 0b01111000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x60, 0x4, 0b00111000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x60, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x60, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x60, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x60, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x60, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x60, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x60, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x60, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x60, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x60, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x60, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x68, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x68, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x68, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x68, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x68, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x68, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x68, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x68, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x68, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x68, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x68, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x68, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x68, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x68, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x68, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x68, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x70, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x70, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x70, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x70, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x70, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x70, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x70, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x70, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x70, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x70, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x70, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x70, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x70, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x70, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x70, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x70, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x78, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x78, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x78, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x78, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x78, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x78, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x78, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x78, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x78, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x78, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x78, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x78, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x78, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x78, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x78, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x78, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x80, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x80, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x80, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x80, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x80, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x80, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x80, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x80, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x80, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x80, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x80, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x80, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x80, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x80, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x80, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x80, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x88, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x88, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x88, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x88, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x88, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x88, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x88, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x88, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x88, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x88, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x88, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x88, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x88, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x88, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x88, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x88, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x90, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x90, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x90, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x90, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x90, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x90, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x90, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x90, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x90, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x90, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x90, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x90, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x90, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x90, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x90, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x90, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x98, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x98, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x98, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x98, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x98, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x98, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x98, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x98, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x98, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x98, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x98, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x98, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x98, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x98, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x98, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0x98, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa0, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa0, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa0, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa0, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa0, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa0, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa0, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa0, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa0, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa0, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa0, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa0, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa0, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa0, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa0, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa0, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa8, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa8, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa8, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa8, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa8, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa8, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa8, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa8, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa8, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa8, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa8, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa8, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa8, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa8, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa8, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xa8, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb0, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb0, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb0, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb0, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb0, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb0, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb0, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb0, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb0, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb0, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb0, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb0, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb0, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb0, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb0, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb0, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb8, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb8, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb8, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb8, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb8, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb8, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb8, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb8, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb8, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb8, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb8, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb8, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb8, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb8, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb8, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xb8, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc0, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc0, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc0, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc0, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc0, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc0, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc0, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc0, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc0, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc0, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc0, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc0, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc0, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc0, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc0, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc0, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc8, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc8, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc8, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc8, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc8, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc8, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc8, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc8, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc8, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc8, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc8, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc8, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc8, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc8, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc8, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xc8, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd0, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd0, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd0, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd0, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd0, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd0, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd0, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd0, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd0, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd0, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd0, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd0, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd0, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd0, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd0, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd0, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd8, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd8, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd8, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd8, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd8, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd8, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd8, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd8, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd8, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd8, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd8, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd8, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd8, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd8, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd8, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xd8, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe0, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe0, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe0, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe0, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe0, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe0, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe0, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe0, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe0, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe0, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe0, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe0, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe0, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe0, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe0, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe0, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe8, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe8, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe8, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe8, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe8, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe8, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe8, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe8, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe8, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe8, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe8, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe8, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe8, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe8, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe8, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xe8, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf0, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf0, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf0, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf0, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf0, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf0, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf0, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf0, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf0, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf0, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf0, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf0, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf0, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf0, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf0, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf0, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf8, 0x0, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf8, 0x1, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf8, 0x2, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf8, 0x3, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf8, 0x4, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf8, 0x5, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf8, 0x6, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf8, 0x7, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf8, 0x8, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf8, 0x9, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf8, 0xa, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf8, 0xb, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf8, 0xc, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf8, 0xd, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf8, 0xe, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
_(0xf8, 0xf, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000)
};
// -- Device prototype --
struct VgaSBDevice {
// Ports
u16 MiscOutputRegisterReadPort;
u16 MiscOutputRegisterWritePort;
u16 GraphicsRegisterIndexPort;
u16 GraphicsRegisterDataPort;
u16 AttributeRegisterIndexPort;
u16 AttributeRegisterDataPort;
u16 CrtRegisterIndexPort;
u16 CrtRegisterDataPort;
u16 SequencerRegisterIndexPort;
u16 SequencerRegisterDataPort;
u16 DacWritePort;
u16 DacReadPort;
u16 DacDataPort;
volatile c8* Plane0;
};
void VgaSBDeviceTMDC_I_TweakGenericRegister(u8 Read, u8 Write, u8 Value, u8 Mask) {
u8 Reg = PortRead8(Read);
Reg &= ~Mask;
Reg |= Value & Mask;
PortWrite8(Write, Reg);
}
void VgaSBDeviceTMDC_I_WriteGraphicsRegister(struct SysbusDevice* Device, u8 Index, u8 Value) {
struct VgaSBDevice* Data = Device->DeviceData;
PortWrite8(Data->GraphicsRegisterIndexPort, Index);
PortWrite8(Data->GraphicsRegisterDataPort, Value);
return;
}
u8 VgaSBDeviceTMDC_I_ReadGraphicsRegister(struct SysbusDevice* Device, u8 Index) {
struct VgaSBDevice* Data = Device->DeviceData;
PortWrite8(Data->GraphicsRegisterIndexPort, Index);
return PortRead8(Data->GraphicsRegisterDataPort);
}
void VgaSBDeviceTMDC_I_TweakGraphicsRegister(struct SysbusDevice* Device, u8 Index, u8 Value, u8 Mask) {
u8 Reg = VgaSBDeviceTMDC_I_ReadGraphicsRegister(Device, Index);
Reg &= ~Mask;
Reg |= Value & Mask;
VgaSBDeviceTMDC_I_WriteGraphicsRegister(Device, Index, Reg);
}
void VgaSBDeviceTMDC_I_WriteInternalPalette(struct SysbusDevice* Device, u8 Index, u8 Value) {
struct VgaSBDevice* Data = Device->DeviceData;
// bit 5 being set to 0 makes the attribute register fetch info from
// the internal palette, it's a really strange design but i suppose it
// makes sense since you don't want to use too many io ports, it also
// has the same address and data ports
PortWrite8(Data->AttributeRegisterIndexPort, (Index & 0x1f));
PortWrite8(Data->AttributeRegisterIndexPort, Value);
return;
}
u8 VgaSBDeviceTMDC_I_ReadInternalPalette(struct SysbusDevice* Device, u8 Index) {
struct VgaSBDevice* Data = Device->DeviceData;
PortWrite8(Data->AttributeRegisterIndexPort, (Index & 0x1f));
return PortRead8(Data->AttributeRegisterDataPort);
}
void VgaSBDeviceTMDC_I_WriteAttributeRegister(struct SysbusDevice* Device, u8 Index, u8 Value) {
struct VgaSBDevice* Data = Device->DeviceData;
PortWrite8(Data->AttributeRegisterIndexPort, (Index & 0x1f) | 0x20);
PortWrite8(Data->AttributeRegisterIndexPort, Value);
return;
}
u8 VgaSBDeviceTMDC_I_ReadAttributeRegister(struct SysbusDevice* Device, u8 Index) {
struct VgaSBDevice* Data = Device->DeviceData;
PortWrite8(Data->AttributeRegisterIndexPort, (Index & 0x1f) | 0x20);
return PortRead8(Data->AttributeRegisterDataPort);
}
void VgaSBDeviceTMDC_I_TweakAttributeRegister(struct SysbusDevice* Device, u8 Index, u8 Value, u8 Mask) {
u8 Reg = VgaSBDeviceTMDC_I_ReadAttributeRegister(Device, Index);
Reg &= ~Mask;
Reg |= Value & Mask;
VgaSBDeviceTMDC_I_WriteAttributeRegister(Device, Index, Reg);
}
void VgaSBDeviceTMDC_I_WriteCrtRegister(struct SysbusDevice* Device, u8 Index, u8 Value) {
struct VgaSBDevice* Data = Device->DeviceData;
PortWrite8(Data->CrtRegisterIndexPort, Index);
PortWrite8(Data->CrtRegisterDataPort, Value);
return;
}
u8 VgaSBDeviceTMDC_I_ReadCrtRegister(struct SysbusDevice* Device, u8 Index) {
struct VgaSBDevice* Data = Device->DeviceData;
PortWrite8(Data->CrtRegisterIndexPort, Index);
return PortRead8(Data->CrtRegisterDataPort);
}
void VgaSBDeviceTMDC_I_TweakCrtRegister(struct SysbusDevice* Device, u8 Index, u8 Value, u8 Mask) {
u8 Reg = VgaSBDeviceTMDC_I_ReadCrtRegister(Device, Index);
Reg &= ~Mask;
Reg |= Value & Mask;
VgaSBDeviceTMDC_I_WriteCrtRegister(Device, Index, Reg);
}
void VgaSBDeviceTMDC_I_WriteSequencerRegister(struct SysbusDevice* Device, u8 Index, u8 Value) {
struct VgaSBDevice* Data = Device->DeviceData;
PortWrite8(Data->SequencerRegisterIndexPort, Index);
PortWrite8(Data->SequencerRegisterDataPort, Value);
return;
}
u8 VgaSBDeviceTMDC_I_ReadSequencerRegister(struct SysbusDevice* Device, u8 Index) {
struct VgaSBDevice* Data = Device->DeviceData;
PortWrite8(Data->SequencerRegisterIndexPort, Index);
return PortRead8(Data->SequencerRegisterDataPort);
}
void VgaSBDeviceTMDC_I_TweakSequencerRegister(struct SysbusDevice* Device, u8 Index, u8 Value, u8 Mask) {
u8 Reg = VgaSBDeviceTMDC_I_ReadSequencerRegister(Device, Index);
Reg &= ~Mask;
Reg |= Value & Mask;
VgaSBDeviceTMDC_I_WriteSequencerRegister(Device, Index, Reg);
}
void VgaSBDeviceTMDC_I_WriteDacColor(struct SysbusDevice* Device, u8 Color, u8 Red, u8 Green, u8 Blue) {
struct VgaSBDevice* Data = Device->DeviceData;
PortWrite8(Data->DacWritePort, Color);
PortWrite8(Data->DacDataPort, Red >> 2);
PortWrite8(Data->DacDataPort, Green >> 2);
PortWrite8(Data->DacDataPort, Blue >> 2);
}
s32 VgaSBDeviceTMDC_Enable(struct SysbusDevice* Device) {
return 0;
}
void VgaSBDeviceTMDC_Reset_RealStub(void*) {
return;
}
s32 VgaSBDeviceTMDC_Reset(struct SysbusDevice* Device) {
struct VgaSBDevice* Data = Device->DeviceData;
// Enable display buffer
VgaSBDeviceTMDC_I_TweakGenericRegister(Data->MiscOutputRegisterReadPort, Data->MiscOutputRegisterWritePort, 0x02, 0x02);
// Disable monochrome adapter compatibility (move ports to expected locations)
VgaSBDeviceTMDC_I_TweakGenericRegister(Data->MiscOutputRegisterReadPort, Data->MiscOutputRegisterWritePort, 0x01, 0x01);
// Switch the graphics controller into alphanumeric mode and map VRAM to 0xA0000-0xBFFFF
VgaSBDeviceTMDC_I_TweakGraphicsRegister(Device, 0x06, 0x00 | 0x00, 0x01 | 0x0c);
// Unprotect CRT registers
VgaSBDeviceTMDC_I_TweakCrtRegister(Device, 0x11, 0x00, 0x80);
// Set character height to uh... 16
VgaSBDeviceTMDC_I_TweakCrtRegister(Device, 0x09, 0x0f, 0x1f);
// Character width can be like uhm... 8
VgaSBDeviceTMDC_I_TweakSequencerRegister(Device, 0x01, 0x01, 0x01);
// Lets go with 80 characters per line
VgaSBDeviceTMDC_I_WriteCrtRegister(Device, 0x01, 80 - 1);
// How about 25 columns... a classic! everything supports it.
VgaSBDeviceTMDC_I_WriteCrtRegister(Device, 0x12, (16 * 25) & 0xff);
VgaSBDeviceTMDC_I_TweakCrtRegister(Device, 0x07, ((16 * 25) & 0x100) ? 2 : 0, 0x42);
// Each line is 80 bytes long, 80 / 2...
VgaSBDeviceTMDC_I_WriteCrtRegister(Device, 0x13, 40);
// Clear upper bits from DAC value
VgaSBDeviceTMDC_I_TweakAttributeRegister(Device, 0x14, 0x00, 0x0f);
// Lets enable every color plane, i can't find any documentation on what it does but i suppose it enables the RGB values
VgaSBDeviceTMDC_I_WriteAttributeRegister(Device, 0x12, 0xf);
// Colors
//VgaSBDeviceTMDC_I_WriteDacColor(Device, 16, 0, 0, 0);
// Set overscan color to 16
VgaSBDeviceTMDC_I_WriteAttributeRegister(Device, 0x11, 0);
// Unlock memory planes 0, 1 and 2
VgaSBDeviceTMDC_I_TweakSequencerRegister(Device, 0x02, 0x07, 0x0f);
// Select font 0 for charsets A and B
VgaSBDeviceTMDC_I_TweakSequencerRegister(Device, 0x03, 0x00, 0x3f);
// Disable odd-even mode
VgaSBDeviceTMDC_I_TweakSequencerRegister(Device, 0x04, 0x04, 0x04);
VgaSBDeviceTMDC_I_TweakGraphicsRegister(Device, 0x05, 0x00, 0x10);
VgaSBDeviceTMDC_I_TweakGraphicsRegister(Device, 0x06, 0x00, 0x02);
// Select write mode 0
VgaSBDeviceTMDC_I_TweakGraphicsRegister(Device, 0x05, 0x00, 0x03);
// Derive data from memory
VgaSBDeviceTMDC_I_TweakGraphicsRegister(Device, 0x00, 0x00, 0x0f);
// Don't rotate data
VgaSBDeviceTMDC_I_TweakGraphicsRegister(Device, 0x03, 0x00, 0x07);
// Don't do any transformations on the data
VgaSBDeviceTMDC_I_TweakGraphicsRegister(Device, 0x03, 0x00, 0x18);
// Bitmask
VgaSBDeviceTMDC_I_TweakGraphicsRegister(Device, 0x08, 0xff, 0xff);
// Only write to plane 2
VgaSBDeviceTMDC_I_TweakSequencerRegister(Device, 0x02, 0x04, 0x0f);
// Load font 0
for (int i = 0; i < 256; i++) {
for (int j = 0; j < 32; j++) {
Data->Plane0[i * 32 + j] = VgaFont[i][j];
}
}
// Only write to plane 0 and 1
VgaSBDeviceTMDC_I_TweakSequencerRegister(Device, 0x02, 0x03, 0x0f);
// Map VRAM to 0xB8000-0xBFFFF
VgaSBDeviceTMDC_I_TweakGraphicsRegister(Device, 0x06, 0x0c, 0x0c);
// Set VRAM start address to start of VRAM
VgaSBDeviceTMDC_I_WriteCrtRegister(Device, 0x0D, 0);
VgaSBDeviceTMDC_I_WriteCrtRegister(Device, 0x0C, 0);
// Ensure chain mode is off
VgaSBDeviceTMDC_I_TweakGraphicsRegister(Device, 0x04, 0x08, 0x00);
// Enable odd/even mode
VgaSBDeviceTMDC_I_TweakGraphicsRegister(Device, 0x05, 0x10, 0x10);
VgaSBDeviceTMDC_I_TweakGraphicsRegister(Device, 0x06, 0x02, 0x02);
VgaSBDeviceTMDC_I_TweakSequencerRegister(Device, 0x04, 0x00, 0x04);
return 0;
}
s32 VgaSBDeviceTMDC_GetPaletteSize(struct SysbusDevice* Device) {
return 15;
}
s32 VgaSBDeviceTMDC_SetPaletteColor(struct SysbusDevice* Device, u32 ID, u8 Red, u8 Green, u8 Blue) {
if (ID >= 16) return -1;
VgaSBDeviceTMDC_I_WriteDacColor(Device, ID, Red, Green, Blue);
VgaSBDeviceTMDC_I_WriteInternalPalette(Device, ID, ID);
VgaSBDeviceTMDC_I_WriteAttributeRegister(Device, 0x12, 0xf);
return 0;
}
s32 VgaSBDeviceTMDC_SetCharacter(struct SysbusDevice* Device, u32 Row, u32 Col, c8 Char, u32 FG, u32 BG) {
if (Row > 25 || Col > 80) return -1;
struct VgaSBDevice* Data = Device->DeviceData;
Data->Plane0[0x18000 + (Row * 80 + Col) * 2 ] = Char;
Data->Plane0[0x18000 + (Row * 80 + Col) * 2 + 1] = ((FG & 0xf) << 4) | (BG & 0xf);
return 0;
}
struct TextModeDisplayCapability VgaSBDeviceTextModeDisplayCapability = {
.Enable = VgaSBDeviceTMDC_Enable,
.Reset = VgaSBDeviceTMDC_Reset,
.GetPaletteSize = VgaSBDeviceTMDC_GetPaletteSize,
.SetPaletteColor = VgaSBDeviceTMDC_SetPaletteColor,
.SetCharacter = VgaSBDeviceTMDC_SetCharacter
};
struct SysbusDeviceDescription* VgaSBDevice = 0;
s32 VgaSBDevice_Create(struct SysbusDevice* Device, void* Data) {
struct VgaSBDevice* UData = KernelHeapAlloc(sizeof(struct VgaSBDevice), 1, KHA_ZERO);
UData->MiscOutputRegisterReadPort = 0x03cc;
UData->MiscOutputRegisterWritePort= 0x03c2;
UData->GraphicsRegisterIndexPort = 0x03ce;
UData->GraphicsRegisterDataPort = 0x03cf;
UData->AttributeRegisterIndexPort = 0x03c0;
UData->AttributeRegisterDataPort = 0x03c1;
UData->CrtRegisterIndexPort = 0x03d4;
UData->CrtRegisterDataPort = 0x03d5;
UData->SequencerRegisterIndexPort = 0x03c4;
UData->SequencerRegisterDataPort = 0x03c5;
UData->DacWritePort = 0x03c8;
UData->DacReadPort = 0x03c7;
UData->DacDataPort = 0x03c9;
UData->Plane0 = (c8*)0xa0000;
Device->DeviceData = UData;
return 0;
}
s32 VgaSBDevice_Delete(struct SysbusDevice* Device) {
KernelHeapFree(Device->DeviceData);
return 0;
}
void* VgaSBDevice_GetCapability(struct SysbusDevice* Device, struct SysbusDeviceCapability* Capability) {
if (Capability == TextModeDisplayCapabilityGetCapability()) {
return &VgaSBDeviceTextModeDisplayCapability;
} else return 0;
}
// -- Device creation/destruction --
bool VgaInitialized = false;
bool VgaIsInitialized() { return VgaInitialized; }
void VgaInitialize() {
if (!TextModeDisplayCapabilityIsInitialized()) {
TextModeDisplayCapabilityInitialize();
}
VgaSBDevice = SysbusCreateDeviceDescription();
VgaSBDevice->DeviceName = "VGA Compatible Device";
VgaSBDevice->CreateDevice = VgaSBDevice_Create;
VgaSBDevice->DeleteDevice = VgaSBDevice_Delete;
VgaSBDevice->GetCapability = VgaSBDevice_GetCapability;
VgaInitialized = true;
}
struct SysbusDevice* VgaCreateDevice(struct SysbusDevice* Parent) {
return SysbusCreateDevice(VgaSBDevice, Parent, NULL);
}
void VgaDeleteDevice(struct SysbusDevice* Device) {
SysbusDeleteDevice(Device);
}

24
lcrash/driver/vga.h Normal file
View File

@ -0,0 +1,24 @@
#pragma once
#include <lcrash/types.h>
#include <lcrash/driver/sysbus.h>
/**
* Initialize the VGA driver
*/
void VgaInitialize();
/**
* Vga drivers are ready
*/
bool VgaIsInitialized();
/**
* Create a legacy VGA device, due to how VGA works, only one may exist at a time :D
*/
struct SysbusDevice* VgaCreateDevice(struct SysbusDevice* Parent);
/**
* Delete a legacy VGA device
*/
void VgaDeleteDevice(struct SysbusDevice* Device);

180
lcrash/irq.c Normal file
View File

@ -0,0 +1,180 @@
#include <lcrash/irq.h>
#include <lcrash/util.h>
#include <lcrash/debug/debug.h>
#define PICMCMD 0x0020
#define PICMDAT 0x0021
#define PICSCMD 0x00A0
#define PICSDAT 0x00A1
struct IrqHandlerGate {
/// Gate number
u8 GateNumber;
/// Hooks
struct IrqHandlerHook* Hooks;
};
struct [[gnu::packed]] IrqHandlerDescriptor {
u16 Offset0;
u16 Segment;
u16 Flags;
u16 Offset1;
u32 Offset2;
u32 Reserved;
};
struct [[gnu::packed]] IrqHandlerIDTR {
u16 Length;
struct IrqHandlerDescriptor* Offset;
};
struct IrqHandlerInterruptFrame {
u64 PrevInstructionAddress;
u64 PrevInstructionSegment;
u64 PrevFlags;
u64 PrevStackAddress;
u64 PrevStackSegment;
};
struct IrqHandlerGate IrqHandlerGates[256] = {};
[[gnu::aligned(16)]]
struct IrqHandlerDescriptor IrqHandlerDescriptors[256] = {};
/// Check for spurious IRQs
bool IrqHandlerCheckRealIRQ(u64 Interrupt) {
if (Interrupt == 0x27) {
PortWrite8(PICMCMD, 0x0B); // RDISR
if (PortRead8(PICMDAT) & 0x80) return false;
}
if (Interrupt >= 0x28 && Interrupt <= 0x2f) {
PortWrite8(PICSCMD, 0x0B); // RDISR
if (PortRead8(PICSDAT) & 0x80) {
PortWrite8(PICMCMD, 0x20);
return false;
}
}
return true;
}
/// Send an EOI to the PIC
void IrqHandlerSendEOI(u64 Interrupt) {
if (Interrupt >= 0x20 && Interrupt < 0x30) {
if (Interrupt >= 0x28) PortWrite8(PICSCMD, 0x20); // EOI
PortWrite8(PICMCMD, 0x20); // EOI
}
}
/// Handle an interrupt
[[gnu::target("general-regs-only")]]
void IrqHandlerHandleInterrupt(struct IrqHandlerInterruptFrame* Frame, u64 Interrupt) {
// Panic("Got interrupt");
IrqHandlerSendEOI(Interrupt);
return;
}
/// Handle an exception
[[gnu::target("general-regs-only")]]
void IrqHandlerHandleException(struct IrqHandlerInterruptFrame* Frame, u64 ErrorCode, u64 Interrupt) {
//Panic("Got exception");
IrqHandlerSendEOI(Interrupt);
return;
}
s32 IrqHandlerInitialize() {
extern int IrqHandlerISRTable;
void* ISRTable = &IrqHandlerISRTable;
// Table stating if an interrupt is an error or not
bool Error[256] = {
0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 1, 1, 1, 1, 0,
0, 1, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
// Fill IDT
for (int i = 0; i < 256; i++) {
u64 Offset = (u64)ISRTable;
IrqHandlerDescriptors[i].Segment = 0x10; // TODO: This shouldnt be hardcoded
IrqHandlerDescriptors[i].Flags = Error[i] ? 0x8F00 : 0x8E00;
IrqHandlerDescriptors[i].Offset0 = Offset & 0xffff;
IrqHandlerDescriptors[i].Offset1 = (Offset >> 16) & 0xffff;
IrqHandlerDescriptors[i].Offset2 = Offset >> 32 & 0xffffffff;
ISRTable += 0x20;
}
// Load the IDT
struct IrqHandlerIDTR IDTR;
IDTR.Offset = IrqHandlerDescriptors;
IDTR.Length = 256 * 16 - 1;
asm ("lidt %0" :: "m" (IDTR));
// Drop to assembly and do a long jump to get our IRQ's working
asm ("call IrqHandlerApplyStateChange");
// TODO: Disable APIC until APIC support is added
// Reconfigure legacy PIC (TODO: Switch to APIC)
PortWrite8(PICMCMD, 0x11); // Initialize / cascade
PortWrite8(PICSCMD, 0x11);
PortWrite8(PICMDAT, 0x20); // Map master PIC IRQs to 0x20-0x27
PortWrite8(PICSDAT, 0x28); // Map slave PIC IRQS to 0x28-0x2f
PortWrite8(PICMDAT, 0x04); // Slave at IRQ2
PortWrite8(PICSDAT, 0x02); // Slave ID 2
PortWrite8(PICMDAT, 0x01); // Switch to 8086 mode
PortWrite8(PICSDAT, 0x01);
PortWrite8(PICMDAT, 0x01); // Respect all external interrupts except the PIC timer because its fucking stupid
PortWrite8(PICSDAT, 0x00);
return 0;
}
void IrqHandlerEnableInterrupts() { asm ("sti"); }
void IrqHandlerDisableInterrupts() { asm ("cli"); }
s32 IrqHandlerAttach(u8 Gate, struct IrqHandlerHook* Hook) {
return -1;
}
s32 IrqHandlerDetach(struct IrqHandlerHook* Hook) {
return -1;
}

62
lcrash/irq.h Normal file
View File

@ -0,0 +1,62 @@
#pragma once
#include <lcrash/types.h>
/**
* A specific IRQ gate
* \internal
*/
struct IrqHandlerGate;
/**
* A hook called on an interrupt
*/
struct IrqHandlerHook {
/// Higher priority values called first
u32 Priority;
/**
* The hook itself.
*
* \return 1 to cancel uncalled hooks
* 0 on success
* -1 on failure
*/
s32 (*HookCall)();
/**
* Next hook
* \internal
*/
struct IrqHandlerHook* Next;
/**
* Attached gate
* \internal
*/
struct IrqHandlerGate* Gate;
};
/**
* Initialize the IRQ handler
*
* \return 0 on success
*/
s32 IrqHandlerInitialize();
/**
* Hook an interrupt
*
* \return 0 on success
*/
s32 IrqHandlerAttach(u8 Gate, struct IrqHandlerHook* Hook);
/**
* Remove a hook
*
* \return 0 on success
*/
s32 IrqHandlerDetach(struct IrqHandlerHook* Hook);
void IrqHandlerDisableInterrupts();
void IrqHandlerEnableInterrupts();

111
lcrash/irq.s Normal file
View File

@ -0,0 +1,111 @@
.align 0x1000
.global IrqHandlerApplyStateChange
.local a
IrqHandlerApplyStateChange:
push %r14
push %r15
// Disable interrupts
cli
// Get pointer to IrqHandlerApplyStateChange
lea (%rip), %r15
a: sub $(a - IrqHandlerApplyStateChange), %r15
// Get pointer to IrqHandlerApplyStateChangeReprotect
mov %r15, %r14
add $(IrqHandlerApplyStateChangeFinish - IrqHandlerApplyStateChange), %r14
// Jump far
sub $6, %rsp
movl %r14d, (%rsp)
movw %cs, 4(%rsp)
.code32 // HACK: This isn't correct it's valid in 64-bit mode, but GAS doesn't seem to agree
ljmp *(%esp)
.code64
.local IrqHandlerApplyStateChangeFinish
IrqHandlerApplyStateChangeFinish:
// Fix registers
add $6, %rsp
pop %r15
pop %r14
// Enable interrupts
// sti
// Return
ret
// Generate IRQ handlers
.macro gen_irqh int, err
.set pta, .
// Disable interrupts
cli
// Call the thing
.if \err
popq %rsi
movq %rsp, %rdi
movq $\int, %rdx
call IrqHandlerHandleException
.else
movq %rsp, %rdi
movq $\int, %rsi
call IrqHandlerHandleInterrupt
.endif
// Re-enable interrupts
sti
// Goodbye :3
iretq
// Pad area
.if (0x20 - (. - pta)) < 0
.error "IRQ Handler is too long"
.elseif (0x20 - (. - pta)) > 0
.zero 0x20 - (. - pta)
.endif
.endm
.global IrqHandlerISRTable
IrqHandlerISRTable:
gen_irqh 0, 0
gen_irqh 1, 0
gen_irqh 2, 0
gen_irqh 3, 0
gen_irqh 4, 0
gen_irqh 5, 0
gen_irqh 6, 0
gen_irqh 7, 0
gen_irqh 8, 1
gen_irqh 9, 0
gen_irqh 10, 1
gen_irqh 11, 1
gen_irqh 12, 1
gen_irqh 13, 1
gen_irqh 14, 1
gen_irqh 15, 0
gen_irqh 16, 0
gen_irqh 17, 1
gen_irqh 18, 0
gen_irqh 19, 0
gen_irqh 20, 0
gen_irqh 21, 1
gen_irqh 22, 0
gen_irqh 23, 0
gen_irqh 24, 0
gen_irqh 25, 0
gen_irqh 26, 0
gen_irqh 27, 0
gen_irqh 28, 0
gen_irqh 29, 1
gen_irqh 30, 1
gen_irqh 31, 0
.equ i, 32
.rept 256 - 32
gen_irqh i, 0
.equ i, i + 1
.endr

View File

@ -9,12 +9,84 @@
#include <lcrash/debug/debug.h> #include <lcrash/debug/debug.h>
#include <lcrash/driver/sysbus.h> #include <lcrash/driver/sysbus.h>
#include <lcrash/mm/virt.h> #include <lcrash/mm/virt.h>
#include <lcrash/driver/cap/textdisplay.h>
#include <lcrash/irq.h>
#include "types.h" #include "types.h"
#include "lnxboot.h" #include "lnxboot.h"
#include "efi/efi.h" #include "efi/efi.h"
struct SysbusDevice* TryFindScreen(struct SysbusDevice* Device) {
if (SysbusGetCapability(Device, TextModeDisplayCapabilityGetCapability()) != NULL) {
return Device;
}
for (int i = 0; i < Device->ChildCount; i++) {
struct SysbusDevice* ChildDevice = TryFindScreen(Device->Children[i]);
if (ChildDevice != NULL) return ChildDevice;
}
return NULL;
}
/**
* Fill a screen range with a character.
* Positions are 1-indexed
*/
void FillScreenCharRange(struct SysbusDevice* Device, struct TextModeDisplayCapability* TMDC, u32 R0, u32 C0, u32 R1, u32 C1, c8 Char, u32 FG, u32 BG) {
R0 -= 1;
R1 -= 1;
C0 -= 1;
C1 -= 1;
for (int r = R0; r <= R1; r++) {
for (int c = C0; c <= C1; c++) {
TMDC->SetCharacter(Device, r, c, Char, FG, BG);
}
}
}
/**
* Draw text at a location
* Positions are 1-indexed
*/
void DrawTextBox(struct SysbusDevice* Device, struct TextModeDisplayCapability* TMDC, u32 R0, u32 C0, u32 R1, u32 C1, u32 FG, u32 BG, c8* Text) {
R0 -= 1;
R1 -= 1;
C0 -= 1;
C1 -= 1;
bool InText = true;
int Row = R0;
int Col = 0;
for (Row = R0; Row <= R1; Row++) {
for (Col = C0; Col <= C1;) {
if (*Text == 0) InText = false;
if (InText) {
c8 Char = *Text;
if (Char >= 'a' && Char <= 'z') Char = Char - 'a' + 'A';
if (Char == '\r') {
Col = C0;
} else if (Char == '\n') {
Row += 1;
} else {
TMDC->SetCharacter(Device, Row, Col, Char, FG, BG);
Col += 1;
}
Text += 1;
} else {
TMDC->SetCharacter(Device, Row, Col, ' ', FG, BG);
Col += 1;
}
}
}
return;
}
[[noreturn]] [[noreturn]]
void entry64(struct boot_params* BootParams) { void entry64(struct boot_params* BootParams) {
BootBootParams = BootParams; BootBootParams = BootParams;
@ -36,6 +108,12 @@ void entry64(struct boot_params* BootParams) {
// Initialize the kernel heap // Initialize the kernel heap
if (KernelHeapInitialize()) while (1) {} if (KernelHeapInitialize()) while (1) {}
// Initialize the IRQ handler
if (IrqHandlerInitialize()) while (1) {}
// Enable interrupts
IrqHandlerEnableInterrupts();
// Initialize the extended debugging information block // Initialize the extended debugging information block
if (DebugInitialize()) while (1) {} if (DebugInitialize()) while (1) {}
@ -54,6 +132,33 @@ void entry64(struct boot_params* BootParams) {
// Initialize PCI code.. // Initialize PCI code..
PciInitialize(); PciInitialize();
// Try to find a screen and write some crap to it.
// TODO: REMOVE WHEN DONE WITH DISPLAY DRIVERS
if (!TextModeDisplayCapabilityIsInitialized()) TextModeDisplayCapabilityInitialize();
struct SysbusDevice* Screen = TryFindScreen(SysbusGetRootDevice());
if (Screen == 0) Panic("No screen found");
struct TextModeDisplayCapability* ScreenTMDC = SysbusGetCapability(Screen, TextModeDisplayCapabilityGetCapability());
if (ScreenTMDC->Reset(Screen)) Panic("Failed to reset screen");
if (ScreenTMDC->Enable(Screen)) Panic("Failed to enable screen");
// Set color palette
ScreenTMDC->SetPaletteColor(Screen, 0, 0, 0, 0 );
ScreenTMDC->SetPaletteColor(Screen, 1, 200, 0, 0 );
ScreenTMDC->SetPaletteColor(Screen, 2, 200, 200, 200);
// Clear screen
FillScreenCharRange(Screen, ScreenTMDC, 1, 1, 25, 80, ' ', 1, 1);
// Draw header
DrawTextBox(Screen, ScreenTMDC, 4, 32, 4, 47, 2, 1, " YOU FUCKED UP! ");
// Draw body
DrawTextBox(Screen, ScreenTMDC, 6, 5, 8, 75, 1, 2, "A fatal error has occurred and Lindows has shut down to prevent damage to your device.");
DrawTextBox(Screen, ScreenTMDC, 10, 5, 13, 75, 1, 2, "If this error occurs again after a reboot, check the logs in `C:/Windows/Logs/`. If you are unable to correct the error, try dumping the system and analyzing it in GDB or submitting a bug report with the dump and logs included.");
DrawTextBox(Screen, ScreenTMDC, 21, 5, 22, 75, 1, 2, "Press any key to reboot.\r\nPress ESC to dump the system state to `C:/Windows/SystemDump/`.");
// Hang :) // Hang :)
while (1) {} while (1) {}
} }

View File

@ -262,6 +262,12 @@ void* KernelHeapAllocInternal(u32 Size, u32 Align, u32 Flags, u32 Iteration) {
Block->Free = 0; Block->Free = 0;
Block->Size = Size; Block->Size = Size;
// Transform block data
u8* BlockData = (void*)Block + sizeof(struct KernelHeapBlock);
if (Flags & KHA_ZERO) {
for (int i = 0; i < Block->Size; i++) BlockData[i] = 0;
}
return (void*)Block + sizeof(struct KernelHeapBlock); return (void*)Block + sizeof(struct KernelHeapBlock);
} }
} }

View File

@ -12,6 +12,9 @@ int KernelHeapInitialize();
*/ */
void* KernelHeapAlloc(u32 Size, u32 Align, u32 Flags); void* KernelHeapAlloc(u32 Size, u32 Align, u32 Flags);
/// Flag for KernelHeapAlloc: Zero memory
#define KHA_ZERO 1
/** /**
* Free memory * Free memory
*/ */

View File

@ -12,11 +12,59 @@ void VmemMapMemory(void* Phys, void* Virt, u64 Size) {
if ((PhysStart | VirtStart | Size) & 0xfff) Panic("VmemMapMemory: Addresses not page aligned"); if ((PhysStart | VirtStart | Size) & 0xfff) Panic("VmemMapMemory: Addresses not page aligned");
// Map and/or create pages/tables
for (u64 Offset4 = VirtStart; Offset4 < VirtStart + Size; Offset4 += 0x8000000000) { for (u64 Offset4 = VirtStart; Offset4 < VirtStart + Size; Offset4 += 0x8000000000) {
u64 Index4 = (Offset4 >> 48) & 0x1ff;
u64 (*PDPT)[512] = ((*VmemPML4)[Index4] & 1)
? (void*)((*VmemPML4)[Index4] & 0x0007fffffffff000)
: KernelHeapAlloc(sizeof(u64) * 512, 0x1000, KHA_ZERO);
// Add our table
if (!((*VmemPML4)[Index4] & 1)) {
(*VmemPML4)[Index4] = (u64)PDPT | 7;
}
for (u64 Offset3 = Offset4; Offset3 < VirtStart + Size && Offset3 < Offset4 + 0x8000000000; Offset3 += 0x40000000) { for (u64 Offset3 = Offset4; Offset3 < VirtStart + Size && Offset3 < Offset4 + 0x8000000000; Offset3 += 0x40000000) {
u64 Index3 = (Offset3 >> 30) & 0x1ff;
u64 (*PD)[512] = ((*PDPT)[Index3] & 1) && !((*PDPT)[Index3] & 128)
? (void*)((*PDPT)[Index3] & 0x0007fffffffff000)
: KernelHeapAlloc(sizeof(u64) * 512, 0x1000, KHA_ZERO);
// Add our table
if (!((*PDPT)[Index3] & 1)) {
(*PDPT)[Index3] = (u64)PD | 7;
if ((*PDPT)[Index3] & 128) {
// TODO: Copy stuff from the thing
}
}
for (u64 Offset2 = Offset3; Offset2 < VirtStart + Size && Offset2 < Offset3 + 0x40000000; Offset2 += 0x200000) { for (u64 Offset2 = Offset3; Offset2 < VirtStart + Size && Offset2 < Offset3 + 0x40000000; Offset2 += 0x200000) {
u64 Index2 = (Offset2 >> 21) & 0x1ff;
[[maybe_unused]]
u64 (*PT)[512] = ((*PD)[Index2] & 1) && !((*PD)[Index2] & 128)
? (void*)((*PD)[Index2] & 0x0007fffffffff000)
: KernelHeapAlloc(sizeof(u64) * 512, 0x1000, KHA_ZERO);
// ADD OUR TABLE
if (!((*PD)[Index2] & 1)) {
(*PD)[Index2] = (u64)PT | 7;
if ((*PD)[Index2] & 128) {
// TODO: Copy stuff from the thing
}
}
for (u64 Offset1 = Offset2; Offset2 < VirtStart + Size && Offset1 < Offset2 + 0x200000; Offset1 += 0x1000) { for (u64 Offset1 = Offset2; Offset2 < VirtStart + Size && Offset1 < Offset2 + 0x200000; Offset1 += 0x1000) {
[[maybe_unused]]
u64 Index1 = (Offset1 >> 12) & 0x1ff;
// Map the page
(*PT)[Index1] = Offset1 | 7;
} }
} }
} }

View File

@ -4,30 +4,128 @@
#include <lcrash/acpi/acpi.h> #include <lcrash/acpi/acpi.h>
#include <lcrash/debug/debug.h> #include <lcrash/debug/debug.h>
#include <lcrash/driver/sysbus.h> #include <lcrash/driver/sysbus.h>
#include <lcrash/mm/kmalloc.h>
#include <lcrash/driver/vga.h>
#include <lcrash/util.h>
#define PSD_MISC_() PciCreateMiscDevice(Parent, Bus, Device, DeviceHeader->Class, DeviceHeader->Subclass, DeviceHeader->ProgIF)
bool PciIsPresent = false; bool PciIsPresent = false;
bool PciSupportsECM = false; bool PciSupportsECM = false;
void* PciBusses[256] = {}; void* PciBusses[256] = {};
void PciScanDevice(u32 Bus, u32 Device) { struct SysbusDeviceDescription* PciSBHostControllerDevice = 0;
struct PciConfigurationSpaceHeader* DeviceHeader = (struct PciConfigurationSpaceHeader*)(PciBusses[Bus] + Device * 0x800); struct SysbusDeviceDescription* PciSBMiscDevice = 0;
void PciCreateMiscDevice(struct SysbusDevice* Parent, u8 Bus, u8 Device, u8 Class, u8 Subclass, u8 ProgInterface) {
struct SysbusDevice* Dev = SysbusCreateDevice(PciSBMiscDevice, Parent, NULL);
struct PciSBMiscDevice* DeviceData = KernelHeapAlloc(sizeof(PciSBMiscDevice), 1, 0);
DeviceData->Bus = Bus;
DeviceData->Device = Device;
DeviceData->Class = Class;
DeviceData->Subclass = Subclass;
DeviceData->ProgInterface = ProgInterface;
Dev->DeviceName = "PCI Misc Device";
Dev->DeviceData = DeviceData;
}
void PciScanDevice(u32 Bus, u32 Device, struct SysbusDevice* Parent) {
struct PciConfigurationSpaceHeader* DeviceHeader = (struct PciConfigurationSpaceHeader*)(PciBusses[Bus] + Device * 0x8000);
// Is a device connected here? // Is a device connected here?
if (DeviceHeader->VendorID != 0xFFFF) { if (DeviceHeader->VendorID != 0xFFFF) {
while (1) {} if ((DeviceHeader->HeaderType & 3) == 0) {
if (DeviceHeader->Class == 3) {
if (DeviceHeader->Subclass == 0) {
if (DeviceHeader->ProgIF == 0) {
// It looks like theres something in the
// VGA's BARs but i can't seem to find any
// documentation on them, so we'll just use
// legacy vga ports!
// Get VGA drivers ready
if (!VgaIsInitialized()) VgaInitialize();
// QEMU oh so kindly provides us with a builtin version of the VESA BIOS Extensions!
// They break our code. Disable them.
if (DeviceHeader->VendorID == 0x1234 && DeviceHeader->DeviceID == 0x1111) {
PortWrite16(0x01CE, 0x04); // VBE_DISPI_IOPORT_INDEX <= 0x04
PortWrite16(0x01D0, 0x00); // [IDX:04] ENABLED <= FALSE
}
struct SysbusDevice* VgaDev = VgaCreateDevice(Parent);
VgaDev->DeviceName = "VGA Device";
} else PSD_MISC_();
} else PSD_MISC_();
} else if (DeviceHeader->Class == 6) {
if (DeviceHeader->Subclass == 0) {
if (DeviceHeader->HeaderType & 0x80) {
Panic("No support for multiple host controller busses");
} else {
struct PciSBHostController_CreateArgs CreateArgs;
CreateArgs.Bus = Bus;
CreateArgs.Device = Device;
CreateArgs.OwnedBusCount = 1;
CreateArgs.OwnedBusses[0] = Bus;
struct SysbusDevice* HostController = SysbusCreateDevice(
PciSBHostControllerDevice,
Parent, &CreateArgs
);
HostController->DeviceName = "PCI Host Controller";
if (Device == 0) {
for (int i = 1; i < 32; i++) PciScanDevice(Bus, i, HostController);
} else Panic("Bus root inside bus");
}
} else PSD_MISC_();
} else PSD_MISC_();
} else PSD_MISC_();
} }
} }
void PciScanBus(u32 Bus) { s32 PciSBHostControllerDevice_Create(struct SysbusDevice* Device, void* Data) {
// Scan bus devices struct PciSBHostController_CreateArgs* CreateArgs = Data;
for (int i = 0; i < 32; i++) PciScanDevice(Bus, i); struct PciSBHostController* DeviceData = KernelHeapAlloc(sizeof(struct PciSBHostController), 1, KHA_ZERO);
// Copy parameters
DeviceData->Bus = CreateArgs->Bus;
DeviceData->Device = CreateArgs->Device;
DeviceData->OwnedBusCount = CreateArgs->OwnedBusCount;
for (int i = 0; i < DeviceData->OwnedBusCount; i++) DeviceData->OwnedBusses[i] = CreateArgs->OwnedBusses[i];
// Save device data
Device->DeviceData = (void*)DeviceData;
return 0;
}
s32 PciSBHostControllerDevice_Delete(struct SysbusDevice* Device) {
struct PciSBHostController* DeviceData = Device->DeviceData;
// Free device data
KernelHeapFree(DeviceData);
return 0;
} }
void PciInitialize() { void PciInitialize() {
// Try to figure out if we have PCIe // Try to figure out if we have PCIe
if (!AcpiPresent()) Panic("Failed to initialize PCI"); if (!AcpiPresent()) Panic("Failed to initialize PCI");
// Define our devices
PciSBHostControllerDevice = SysbusCreateDeviceDescription();
PciSBHostControllerDevice->DeviceName = "PCI Host Controller";
PciSBHostControllerDevice->CreateDevice = PciSBHostControllerDevice_Create;
PciSBHostControllerDevice->DeleteDevice = PciSBHostControllerDevice_Delete;
PciSBMiscDevice = SysbusCreateDeviceDescription();
PciSBMiscDevice->DeviceName = "PCI Misc Device";
// Acpi
struct AcpiMCFG* BridgeTable = AcpiGetTable("MCFG"); struct AcpiMCFG* BridgeTable = AcpiGetTable("MCFG");
// Guess not // Guess not
@ -39,7 +137,7 @@ void PciInitialize() {
// Identity map our busses because linux doesn't do it for us // Identity map our busses because linux doesn't do it for us
VmemMapMemory( VmemMapMemory(
BridgeTable->Bridges[i].Address, BridgeTable->Bridges[i].Address, BridgeTable->Bridges[i].Address, BridgeTable->Bridges[i].Address,
(BridgeTable->Bridges[i].EndBus - BridgeTable->Bridges[i].StartBus) * 0x100000 (BridgeTable->Bridges[i].EndBus - BridgeTable->Bridges[i].StartBus + 1) * 0x100000
); );
for (int Bus = BridgeTable->Bridges[i].StartBus; Bus < BridgeTable->Bridges[i].EndBus; Bus++) { for (int Bus = BridgeTable->Bridges[i].StartBus; Bus < BridgeTable->Bridges[i].EndBus; Bus++) {
@ -48,7 +146,7 @@ void PciInitialize() {
} }
// Scan the root bus // Scan the root bus
PciScanBus(0); PciScanDevice(0, 0, SysbusGetRootDevice());
return; return;
} }

View File

@ -11,19 +11,72 @@ struct [[gnu::packed]] PciConfigurationSpaceHeader {
u16 Status; u16 Status;
u16 Command; u16 Command;
u8 RevisionID : 8; u8 RevisionID : 8;
u32 ClassCode : 24; u8 ProgIF;
u8 Subclass;
u8 Class;
u8 CacheLineSize; u8 CacheLineSize;
u8 MasterLatencyTimer; u8 MasterLatencyTimer;
u8 HeaderType; u8 HeaderType;
u8 BIST; u8 BIST;
u8 Reserved[0x20]; union {
struct {
u32 BAR0;
u32 BAR1;
u32 BAR2;
u32 BAR3;
u32 BAR4;
u32 BAR5;
u32 CIS;
u16 SubsystemVendor;
u16 Subsystem;
u32 ExpansionROM;
u8 Reserved[3];
};
u8 Reserved2[0x20];
};
u8 CapabilitiesPointer; u8 CapabilitiesPointer;
u8 Reserved2[7]; u8 Reserved3[7];
u8 InterruptLine; u8 InterruptLine;
u8 InterruptPin; u8 InterruptPin;
u8 Reserved3[2]; u8 Reserved4[2];
}; };
/**
* PCI Host Controller device for the system bus
*/
struct PciSBHostController {
u8 Bus;
u8 Device;
u8 OwnedBusCount;
u8 OwnedBusses[8];
};
/**
* PCI Host Controller device create arguments
*/
struct PciSBHostController_CreateArgs {
u8 Bus;
u8 Device;
u8 OwnedBusCount;
u8 OwnedBusses[8];
};
/**
* Unknown PCI device
*/
struct PciSBMiscDevice {
u8 Bus;
u8 Device;
u8 Class;
u8 Subclass;
u8 ProgInterface;
};
typedef struct PciSBMiscDevice PciSBMiscDevice_CreateArgs;
/** /**
* Initialize the PCI code. * Initialize the PCI code.
*/ */

View File

@ -28,5 +28,5 @@ entry64: // 64-bit entry point for kernel decompression
.section ".bss" .section ".bss"
init_stack: // this should be sufficient for kernel decompression init_stack: // this should be sufficient for kernel decompression
.skip 0x8000, 0 .skip 0x10000, 0
einit_stack: einit_stack:

View File

@ -46,7 +46,7 @@ payload_offset: .long _end // cckernel_start
payload_length: .long _KKCLEN // cckernel_size payload_length: .long _KKCLEN // cckernel_size
setup_data: .quad 0 setup_data: .quad 0
pref_address: .quad 0 pref_address: .quad 0
init_size: .long 0x20000 // a bit of space init_size: .long 0x40000 // a bit of space
handover_offset: .long 0 // TODO handover_offset: .long 0 // TODO
kernel_info_offset: .long 0 // TODO kernel_info_offset: .long 0 // TODO
/* .globl entrylow /* .globl entrylow

View File

@ -11,3 +11,48 @@ bool CompareMemory(const void* Addr1, const void* Addr2, u32 Length) {
return true; return true;
} }
void PortWrite8(u16 Port, u8 Data) {
asm ( "out %b1, %w0"
:
: "d" (Port),
"a" (Data));
}
void PortWrite16(u16 Port, u16 Data) {
asm ( "out %w1, %w0"
:
: "d" (Port),
"a" (Data));
}
void PortWrite32(u16 Port, u32 Data) {
asm ( "out %1, %w0"
:
: "d" (Port),
"a" (Data));
}
u8 PortRead8(u16 Port) {
u8 Data = 0;
asm ( "in %w1, %b0"
: "=a" (Data)
: "d" (Port));
return Data;
}
u16 PortRead16(u16 Port) {
u16 Data = 0;
asm ( "in %w1, %w0"
: "=a" (Data)
: "d" (Port));
return Data;
}
u32 PortRead32(u16 Port) {
u32 Data = 0;
asm ( "in %w1, %0"
: "=a" (Data)
: "d" (Port));
return Data;
}

View File

@ -6,3 +6,11 @@
* Compare the data at two memory addresses * Compare the data at two memory addresses
*/ */
bool CompareMemory(const void* Addr1, const void* Addr2, u32 Length); bool CompareMemory(const void* Addr1, const void* Addr2, u32 Length);
void PortWrite8(u16 Port, u8 Data);
void PortWrite16(u16 Port, u16 Data);
void PortWrite32(u16 Port, u32 Data);
u8 PortRead8(u16 Port);
u16 PortRead16(u16 Port);
u32 PortRead32(u16 Port);