Complete overhaul of the Legacy system.
Now with reasonable architecture, plus added x86_64.
This commit is contained in:
commit
822cfc4b9e
108
chroma/inc/kernel/boot/boot.h
Normal file
108
chroma/inc/kernel/boot/boot.h
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
|
||||||
|
#ifndef _BOOTLOADER_H_
|
||||||
|
#define _BOOTLOADER_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BOOT_MAGIC "BOOT"
|
||||||
|
|
||||||
|
/* minimum protocol level:
|
||||||
|
* hardcoded kernel name, static kernel memory addresses */
|
||||||
|
#define PROTOCOL_MINIMAL 0
|
||||||
|
/* static protocol level:
|
||||||
|
* kernel name parsed from environment, static kernel memory addresses */
|
||||||
|
#define PROTOCOL_STATIC 1
|
||||||
|
/* dynamic protocol level:
|
||||||
|
* kernel name parsed, kernel memory addresses from ELF or PE symbols */
|
||||||
|
#define PROTOCOL_DYNAMIC 2
|
||||||
|
/* big-endian flag */
|
||||||
|
#define PROTOCOL_BIGENDIAN 0x80
|
||||||
|
|
||||||
|
/* loader types, just informational */
|
||||||
|
#define LOADER_BIOS (0<<2)
|
||||||
|
#define LOADER_UEFI (1<<2)
|
||||||
|
#define LOADER_RPI (2<<2)
|
||||||
|
|
||||||
|
/* framebuffer pixel format, only 32 bits supported */
|
||||||
|
#define FB_ARGB 0
|
||||||
|
#define FB_RGBA 1
|
||||||
|
#define FB_ABGR 2
|
||||||
|
#define FB_BGRA 3
|
||||||
|
|
||||||
|
/* mmap entry, type is stored in least significant tetrad (half byte) of size
|
||||||
|
* this means size described in 16 byte units (not a problem, most modern
|
||||||
|
* firmware report memory in pages, 4096 byte units anyway). */
|
||||||
|
typedef struct {
|
||||||
|
uint64_t ptr;
|
||||||
|
uint64_t size;
|
||||||
|
} __attribute__((packed)) MMapEnt;
|
||||||
|
|
||||||
|
#define MMapEnt_Ptr(a) (a->ptr)
|
||||||
|
#define MMapEnt_Size(a) (a->size & 0xFFFFFFFFFFFFFFF0)
|
||||||
|
#define MMapEnt_Type(a) (a->size & 0xF)
|
||||||
|
#define MMapEnt_IsFree(a) ((a->size&0xF)==1)
|
||||||
|
|
||||||
|
#define MMAP_USED 0 /* don't use. Reserved or unknown regions */
|
||||||
|
#define MMAP_FREE 1 /* usable memory */
|
||||||
|
#define MMAP_ACPI 2 /* acpi memory, volatile and non-volatile as well */
|
||||||
|
#define MMAP_MMIO 3 /* memory mapped IO region */
|
||||||
|
|
||||||
|
#define INITRD_MAXSIZE 16 /* Mb */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/* first 64 bytes is platform independent */
|
||||||
|
uint8_t magic[4]; /* 'BOOT' magic */
|
||||||
|
uint32_t size; /* length of bootboot structure, minimum 128 */
|
||||||
|
uint8_t protocol; /* 1, static addresses, see PROTOCOL_* and LOADER_* above */
|
||||||
|
uint8_t fb_type; /* framebuffer type, see FB_* above */
|
||||||
|
uint16_t numcores; /* number of processor cores */
|
||||||
|
uint16_t bspid; /* Bootsrap processor ID (Local APIC Id on x86_64) */
|
||||||
|
int16_t timezone; /* in minutes -1440..1440 */
|
||||||
|
uint8_t datetime[8]; /* in BCD yyyymmddhhiiss UTC (independent to timezone) */
|
||||||
|
uint64_t initrd_ptr; /* ramdisk image position and size */
|
||||||
|
uint64_t initrd_size;
|
||||||
|
uint8_t *fb_ptr; /* framebuffer pointer and dimensions */
|
||||||
|
uint32_t fb_size;
|
||||||
|
uint32_t fb_width;
|
||||||
|
uint32_t fb_height;
|
||||||
|
uint32_t fb_scanline;
|
||||||
|
|
||||||
|
/* the rest (64 bytes) is platform specific */
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint64_t acpi_ptr;
|
||||||
|
uint64_t smbi_ptr;
|
||||||
|
uint64_t efi_ptr;
|
||||||
|
uint64_t mp_ptr;
|
||||||
|
uint64_t unused0;
|
||||||
|
uint64_t unused1;
|
||||||
|
uint64_t unused2;
|
||||||
|
uint64_t unused3;
|
||||||
|
} x86_64;
|
||||||
|
struct {
|
||||||
|
uint64_t acpi_ptr;
|
||||||
|
uint64_t mmio_ptr;
|
||||||
|
uint64_t efi_ptr;
|
||||||
|
uint64_t unused0;
|
||||||
|
uint64_t unused1;
|
||||||
|
uint64_t unused2;
|
||||||
|
uint64_t unused3;
|
||||||
|
uint64_t unused4;
|
||||||
|
} aarch64;
|
||||||
|
} arch;
|
||||||
|
|
||||||
|
/* from 128th byte, MMapEnt[], more records may follow */
|
||||||
|
MMapEnt mmap;
|
||||||
|
/* use like this:
|
||||||
|
* MMapEnt *mmap_ent = &bootboot.mmap; mmap_ent++;
|
||||||
|
* until you reach bootboot->size */
|
||||||
|
} __attribute__((packed)) bootinfo;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
31
chroma/inc/kernel/chroma.h
Normal file
31
chroma/inc/kernel/chroma.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/************************
|
||||||
|
*** Team Kitty, 2020 ***
|
||||||
|
*** Sync ***
|
||||||
|
***********************/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <kernel/boot/boot.h>
|
||||||
|
#include <kernel/system/io.h>
|
||||||
|
#include <kernel/system/memory.h>
|
||||||
|
|
||||||
|
extern bootinfo bootldr;
|
||||||
|
extern unsigned char* environment;
|
||||||
|
extern uint8_t fb;
|
||||||
|
|
||||||
|
|
||||||
|
void DrawPixel(uint32_t x, uint32_t y, uint32_t color);
|
||||||
|
void FillScreen(uint32_t color);
|
||||||
|
|
||||||
|
void WriteString(const char* string);
|
||||||
|
void WriteChar(const char character);
|
||||||
|
|
||||||
|
void InitInterrupts();
|
||||||
|
void InitSerial();
|
||||||
|
void InitPrint();
|
||||||
|
|
||||||
|
void SetupInitialGDT();
|
||||||
|
void SetupIDT();
|
68
chroma/inc/kernel/system/descriptors.h
Normal file
68
chroma/inc/kernel/system/descriptors.h
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
uint16_t LowLimit;
|
||||||
|
uint16_t BaseLow;
|
||||||
|
uint8_t BaseMid;
|
||||||
|
uint8_t Access;
|
||||||
|
uint8_t Granularity;
|
||||||
|
uint8_t BaseHigh;
|
||||||
|
} GDT_ENTRY;
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
uint16_t Limit;
|
||||||
|
size_t Base;
|
||||||
|
} DESC_TBL;
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
uint16_t BaseLow;
|
||||||
|
uint16_t Segment;
|
||||||
|
uint8_t ISTAndZero;
|
||||||
|
uint8_t SegmentType;
|
||||||
|
uint16_t BaseMid;
|
||||||
|
uint32_t BaseHigh;
|
||||||
|
uint32_t Reserved;
|
||||||
|
} IDT_GATE;
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
uint16_t BaseLow;
|
||||||
|
uint16_t SegmentSelector;
|
||||||
|
uint8_t ISTAndZero;
|
||||||
|
uint8_t Misc;
|
||||||
|
uint16_t BaseHigh;
|
||||||
|
} IDT_ENTRY;
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
uint16_t SegmentLimitLow;
|
||||||
|
uint16_t BaseLow;
|
||||||
|
uint8_t BaseMid1;
|
||||||
|
uint8_t SegmentType;
|
||||||
|
uint8_t SegmentLimitHigh;
|
||||||
|
uint8_t BaseMid2;
|
||||||
|
uint32_t BaseHigh;
|
||||||
|
uint32_t Reserved;
|
||||||
|
} TSS_ENTRY;
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
uint32_t Reserved0;
|
||||||
|
size_t RSP0;
|
||||||
|
size_t RSP1;
|
||||||
|
size_t RSP2;
|
||||||
|
|
||||||
|
size_t Reserved12;
|
||||||
|
|
||||||
|
size_t IST1;
|
||||||
|
size_t IST2;
|
||||||
|
size_t IST3;
|
||||||
|
size_t IST4;
|
||||||
|
size_t IST5;
|
||||||
|
size_t IST6;
|
||||||
|
size_t IST7;
|
||||||
|
|
||||||
|
size_t Reserved34;
|
||||||
|
uint16_t Reserved5;
|
||||||
|
|
||||||
|
uint16_t IOMap;
|
||||||
|
} TSS64;
|
||||||
|
|
80
chroma/inc/kernel/system/interrupts.h
Normal file
80
chroma/inc/kernel/system/interrupts.h
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
size_t ss;
|
||||||
|
size_t rsp;
|
||||||
|
size_t rflags;
|
||||||
|
size_t cs;
|
||||||
|
size_t rip;
|
||||||
|
} INTERRUPT_FRAME;
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) {
|
||||||
|
size_t ErrorCode;
|
||||||
|
size_t rip;
|
||||||
|
size_t cs;
|
||||||
|
size_t rflags;
|
||||||
|
size_t rsp;
|
||||||
|
size_t ss;
|
||||||
|
} EXCEPTION_FRAME;
|
||||||
|
|
||||||
|
static void* IRQ_Handlers[16] = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
void IRQ_Common(INTERRUPT_FRAME* Frame, size_t Interupt);
|
||||||
|
void ISR_Common(INTERRUPT_FRAME* Frame, size_t Interrupt);
|
||||||
|
void ISR_Error_Common(INTERRUPT_FRAME* Frame, size_t ErrorCode, size_t Exception);
|
||||||
|
|
||||||
|
void RemapIRQControllers();
|
||||||
|
|
||||||
|
void ISR0Handler(INTERRUPT_FRAME* Frame); // Divide-By-Zero
|
||||||
|
void ISR1Handler(INTERRUPT_FRAME* Frame); // Debug
|
||||||
|
void ISR2Handler(INTERRUPT_FRAME* Frame); // Non-Maskable Interrupt
|
||||||
|
void ISR3Handler(INTERRUPT_FRAME* Frame); // Breakpoint
|
||||||
|
void ISR4Handler(INTERRUPT_FRAME* Frame); // Overflow
|
||||||
|
void ISR5Handler(INTERRUPT_FRAME* Frame); // Out-of-Bounds
|
||||||
|
void ISR6Handler(INTERRUPT_FRAME* Frame); // Invalid Opcode
|
||||||
|
void ISR7Handler(INTERRUPT_FRAME* Frame); // No Coprocessor
|
||||||
|
void ISR8Handler(INTERRUPT_FRAME* Frame, size_t ErrorCode); // Double Fault
|
||||||
|
void ISR9Handler(INTERRUPT_FRAME* Frame); // Coprocessor Overrun
|
||||||
|
void ISR10Handler(INTERRUPT_FRAME* Frame, size_t ErrorCode); // Invalid TSS
|
||||||
|
void ISR11Handler(INTERRUPT_FRAME* Frame, size_t ErrorCode); // Segment Not Present
|
||||||
|
void ISR12Handler(INTERRUPT_FRAME* Frame, size_t ErrorCode); // Stack Segment Fault
|
||||||
|
void ISR13Handler(INTERRUPT_FRAME* Frame, size_t ErrorCode); // General Protection Fault
|
||||||
|
void ISR14Handler(INTERRUPT_FRAME* Frame, size_t ErrorCode); // Page Fault
|
||||||
|
void ISR15Handler(INTERRUPT_FRAME* Frame); // Unknown Interrupt
|
||||||
|
void ISR16Handler(INTERRUPT_FRAME* Frame); // Math Error / Coprocessor Fault
|
||||||
|
void ISR17Handler(INTERRUPT_FRAME* Frame, size_t ErrorCode); // Alignment Error
|
||||||
|
void ISR18Handler(INTERRUPT_FRAME* Frame); // Machine Check
|
||||||
|
void ISR19Handler(INTERRUPT_FRAME* Frame); // SSE Math Error
|
||||||
|
void ISR20Handler(INTERRUPT_FRAME* Frame); // Virtualization
|
||||||
|
void ISR21Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void ISR22Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void ISR23Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void ISR24Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void ISR25Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void ISR26Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void ISR27Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void ISR28Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void ISR29Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void ISR30Handler(INTERRUPT_FRAME* Frame, size_t ErrorCode); // Security Fault
|
||||||
|
void ReservedISRHandler(INTERRUPT_FRAME* Frame);
|
||||||
|
|
||||||
|
|
||||||
|
void IRQ0Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void IRQ1Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void IRQ2Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void IRQ3Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void IRQ4Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void IRQ5Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void IRQ6Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void IRQ7Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void IRQ8Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void IRQ9Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void IRQ10Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void IRQ11Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void IRQ12Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void IRQ13Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void IRQ14Handler(INTERRUPT_FRAME* Frame);
|
||||||
|
void IRQ15Handler(INTERRUPT_FRAME* Frame);
|
63
chroma/inc/kernel/system/io.h
Normal file
63
chroma/inc/kernel/system/io.h
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
#include <kernel/system/descriptors.h>
|
||||||
|
|
||||||
|
uint8_t kbdSBuffer[8];
|
||||||
|
uint8_t InputBuffer[128];
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t ACK;
|
||||||
|
uint8_t SelfTest;
|
||||||
|
uint8_t Echo;
|
||||||
|
uint8_t EchoCount;
|
||||||
|
uint8_t Error;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} KBD_FLAGS;
|
||||||
|
|
||||||
|
KBD_FLAGS KbdFlags;
|
||||||
|
|
||||||
|
|
||||||
|
DESC_TBL ReadGDT(void);
|
||||||
|
void WriteGDT(DESC_TBL GDTData);
|
||||||
|
|
||||||
|
DESC_TBL ReadIDT(void);
|
||||||
|
void WriteIDT(DESC_TBL IDTData);
|
||||||
|
|
||||||
|
uint16_t ReadLDT(void);
|
||||||
|
void WriteLDT(uint16_t LDTData);
|
||||||
|
|
||||||
|
uint16_t ReadTSR(void);
|
||||||
|
void WriteTSR(uint16_t TSRData);
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t ReadPort(uint16_t Port, int Length);
|
||||||
|
uint32_t WritePort(uint16_t Port, uint32_t Data, int Length);
|
||||||
|
size_t ReadModelSpecificRegister(size_t MSR);
|
||||||
|
size_t WriteModelSpecificRegister(size_t MSR, size_t Data);
|
||||||
|
|
||||||
|
uint32_t ReadVexMXCSR(void);
|
||||||
|
uint32_t WriteVexMXCSR(uint32_t Data);
|
||||||
|
|
||||||
|
uint32_t ReadMXCSR(void);
|
||||||
|
uint32_t WriteMXCSR(uint32_t Data);
|
||||||
|
|
||||||
|
size_t ReadControlRegister(int CRX);
|
||||||
|
size_t WriteControlRegister(int CRX, size_t Data);
|
||||||
|
|
||||||
|
size_t ReadExtendedControlRegister(size_t XCRX);
|
||||||
|
size_t WriteExtendedControlRegister(size_t XCRX, size_t Data);
|
||||||
|
|
||||||
|
// XCS = Extended Code Segment
|
||||||
|
size_t ReadXCS(void);
|
||||||
|
|
||||||
|
void UpdateKeyboard(uint8_t scancode);
|
||||||
|
void WaitFor8042();
|
||||||
|
void Send8042(size_t);
|
||||||
|
|
||||||
|
void WriteSerialChar(const char);
|
||||||
|
void WriteSerialString(const char*, size_t);
|
||||||
|
|
||||||
|
int SerialPrintf(const char* restrict format, ...);
|
||||||
|
|
||||||
|
void* memcpy(void* dest, void const* src, size_t len);
|
||||||
|
void* memset(void* dst, int src, size_t len);
|
25
chroma/inc/kernel/system/memory.h
Normal file
25
chroma/inc/kernel/system/memory.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define PAGE_SIZE 4096
|
||||||
|
#define PAGES_PER_BUCKET 8
|
||||||
|
|
||||||
|
#define OFFSET_BIT(i) Memory[i / PAGES_PER_BUCKET]
|
||||||
|
#define SET_BIT(i) OFFSET_BIT(i) = OFFSET_BIT(i) | (1 << (i % PAGES_PER_BUCKET))
|
||||||
|
#define UNSET_BIT(i) OFFSET_BIT(i) = OFFSET_BIT(i) & (~(1 << (i % PAGES_PER_BUCKET)))
|
||||||
|
#define READ_BIT(i) ((OFFSET_BIT(i) >> (i % PAGES_PER_BUCKET)) & 0x1)
|
||||||
|
#define GET_BUCKET32(i) (*((uint32_t*) (&Memory[i / 32])))
|
||||||
|
|
||||||
|
#define PAGE_ALIGN(addr) (((addr) & 0xFFFFF000) + 0x1000)
|
||||||
|
|
||||||
|
extern size_t end;
|
||||||
|
|
||||||
|
void InitMemoryManager();
|
||||||
|
|
||||||
|
size_t AllocatePage();
|
||||||
|
|
||||||
|
void FreePage(size_t PageNumber);
|
||||||
|
|
||||||
|
size_t FirstFreePage();
|
||||||
|
|
||||||
|
void MemoryTest();
|
466
chroma/inc/kernel/video/bitmapfont.h
Normal file
466
chroma/inc/kernel/video/bitmapfont.h
Normal file
|
@ -0,0 +1,466 @@
|
||||||
|
/************************
|
||||||
|
*** Team Kitty, 2019 ***
|
||||||
|
*** Sync ***
|
||||||
|
***********************/
|
||||||
|
|
||||||
|
// This file contains all of the bitmap fonts made by me (Curle) and taken from the public domain
|
||||||
|
// eg. http://dimensionalrift.homelinux.net/combuster/mos3/?p=viewsource&file=/modules/gfx/font8_8.asm
|
||||||
|
|
||||||
|
|
||||||
|
const unsigned char bitfont_latin[128][8] = {
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space)
|
||||||
|
{ 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!)
|
||||||
|
{ 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (")
|
||||||
|
{ 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#)
|
||||||
|
{ 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($)
|
||||||
|
{ 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%)
|
||||||
|
{ 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&)
|
||||||
|
{ 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (')
|
||||||
|
{ 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (()
|
||||||
|
{ 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ())
|
||||||
|
{ 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*)
|
||||||
|
{ 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.)
|
||||||
|
{ 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/)
|
||||||
|
{ 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0)
|
||||||
|
{ 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1)
|
||||||
|
{ 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2)
|
||||||
|
{ 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3)
|
||||||
|
{ 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4)
|
||||||
|
{ 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5)
|
||||||
|
{ 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6)
|
||||||
|
{ 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7)
|
||||||
|
{ 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8)
|
||||||
|
{ 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9)
|
||||||
|
{ 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:)
|
||||||
|
{ 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (//)
|
||||||
|
{ 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<)
|
||||||
|
{ 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=)
|
||||||
|
{ 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>)
|
||||||
|
{ 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?)
|
||||||
|
{ 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@)
|
||||||
|
{ 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A)
|
||||||
|
{ 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B)
|
||||||
|
{ 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C)
|
||||||
|
{ 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D)
|
||||||
|
{ 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E)
|
||||||
|
{ 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F)
|
||||||
|
{ 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G)
|
||||||
|
{ 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H)
|
||||||
|
{ 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I)
|
||||||
|
{ 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J)
|
||||||
|
{ 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K)
|
||||||
|
{ 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L)
|
||||||
|
{ 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M)
|
||||||
|
{ 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N)
|
||||||
|
{ 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O)
|
||||||
|
{ 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P)
|
||||||
|
{ 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q)
|
||||||
|
{ 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R)
|
||||||
|
{ 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S)
|
||||||
|
{ 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T)
|
||||||
|
{ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U)
|
||||||
|
{ 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V)
|
||||||
|
{ 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W)
|
||||||
|
{ 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X)
|
||||||
|
{ 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y)
|
||||||
|
{ 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z)
|
||||||
|
{ 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([)
|
||||||
|
{ 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\)
|
||||||
|
{ 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (])
|
||||||
|
{ 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_)
|
||||||
|
{ 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`)
|
||||||
|
{ 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a)
|
||||||
|
{ 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b)
|
||||||
|
{ 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c)
|
||||||
|
{ 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d)
|
||||||
|
{ 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e)
|
||||||
|
{ 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f)
|
||||||
|
{ 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g)
|
||||||
|
{ 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h)
|
||||||
|
{ 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i)
|
||||||
|
{ 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j)
|
||||||
|
{ 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k)
|
||||||
|
{ 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l)
|
||||||
|
{ 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m)
|
||||||
|
{ 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n)
|
||||||
|
{ 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o)
|
||||||
|
{ 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p)
|
||||||
|
{ 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q)
|
||||||
|
{ 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r)
|
||||||
|
{ 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s)
|
||||||
|
{ 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t)
|
||||||
|
{ 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u)
|
||||||
|
{ 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v)
|
||||||
|
{ 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w)
|
||||||
|
{ 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x)
|
||||||
|
{ 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y)
|
||||||
|
{ 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z)
|
||||||
|
{ 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|)
|
||||||
|
{ 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (})
|
||||||
|
{ 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const unsigned char bitfont_extra[96][8] = {
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+00A0 (no break space)
|
||||||
|
{ 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00}, // U+00A1 (inverted !)
|
||||||
|
{ 0x18, 0x18, 0x7E, 0x03, 0x03, 0x7E, 0x18, 0x18}, // U+00A2 (dollarcents)
|
||||||
|
{ 0x1C, 0x36, 0x26, 0x0F, 0x06, 0x67, 0x3F, 0x00}, // U+00A3 (pound sterling)
|
||||||
|
{ 0x00, 0x00, 0x63, 0x3E, 0x36, 0x3E, 0x63, 0x00}, // U+00A4 (currency mark)
|
||||||
|
{ 0x33, 0x33, 0x1E, 0x3F, 0x0C, 0x3F, 0x0C, 0x0C}, // U+00A5 (yen)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+00A6 (broken pipe)
|
||||||
|
{ 0x7C, 0xC6, 0x1C, 0x36, 0x36, 0x1C, 0x33, 0x1E}, // U+00A7 (paragraph)
|
||||||
|
{ 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+00A8 (diaeresis)
|
||||||
|
{ 0x3C, 0x42, 0x99, 0x85, 0x85, 0x99, 0x42, 0x3C}, // U+00A9 (copyright symbol)
|
||||||
|
{ 0x3C, 0x36, 0x36, 0x7C, 0x00, 0x00, 0x00, 0x00}, // U+00AA (superscript a)
|
||||||
|
{ 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00}, // U+00AB (<<)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x3F, 0x30, 0x30, 0x00, 0x00}, // U+00AC (gun pointing left)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+00AD (soft hyphen)
|
||||||
|
{ 0x3C, 0x42, 0x9D, 0xA5, 0x9D, 0xA5, 0x42, 0x3C}, // U+00AE (registered symbol)
|
||||||
|
{ 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+00AF (macron)
|
||||||
|
{ 0x1C, 0x36, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00}, // U+00B0 (degree)
|
||||||
|
{ 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00}, // U+00B1 (plusminus)
|
||||||
|
{ 0x1C, 0x30, 0x18, 0x0C, 0x3C, 0x00, 0x00, 0x00}, // U+00B2 (superscript 2)
|
||||||
|
{ 0x1C, 0x30, 0x18, 0x30, 0x1C, 0x00, 0x00, 0x00}, // U+00B2 (superscript 3)
|
||||||
|
{ 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+00B2 (aigu)
|
||||||
|
{ 0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x03}, // U+00B5 (mu)
|
||||||
|
{ 0xFE, 0xDB, 0xDB, 0xDE, 0xD8, 0xD8, 0xD8, 0x00}, // U+00B6 (pilcrow)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00}, // U+00B7 (central dot)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x1E}, // U+00B8 (cedille)
|
||||||
|
{ 0x08, 0x0C, 0x08, 0x1C, 0x00, 0x00, 0x00, 0x00}, // U+00B9 (superscript 1)
|
||||||
|
{ 0x1C, 0x36, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00}, // U+00BA (superscript 0)
|
||||||
|
{ 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00}, // U+00BB (>>)
|
||||||
|
{ 0xC3, 0x63, 0x33, 0xBD, 0xEC, 0xF6, 0xF3, 0x03}, // U+00BC (1/4)
|
||||||
|
{ 0xC3, 0x63, 0x33, 0x7B, 0xCC, 0x66, 0x33, 0xF0}, // U+00BD (1/2)
|
||||||
|
{ 0x03, 0xC4, 0x63, 0xB4, 0xDB, 0xAC, 0xE6, 0x80}, // U+00BE (3/4)
|
||||||
|
{ 0x0C, 0x00, 0x0C, 0x06, 0x03, 0x33, 0x1E, 0x00}, // U+00BF (inverted ?)
|
||||||
|
{ 0x07, 0x00, 0x1C, 0x36, 0x63, 0x7F, 0x63, 0x00}, // U+00C0 (A grave)
|
||||||
|
{ 0x70, 0x00, 0x1C, 0x36, 0x63, 0x7F, 0x63, 0x00}, // U+00C1 (A aigu)
|
||||||
|
{ 0x1C, 0x36, 0x00, 0x3E, 0x63, 0x7F, 0x63, 0x00}, // U+00C2 (A circumflex)
|
||||||
|
{ 0x6E, 0x3B, 0x00, 0x3E, 0x63, 0x7F, 0x63, 0x00}, // U+00C3 (A ~)
|
||||||
|
{ 0x63, 0x1C, 0x36, 0x63, 0x7F, 0x63, 0x63, 0x00}, // U+00C4 (A umlaut)
|
||||||
|
{ 0x0C, 0x0C, 0x00, 0x1E, 0x33, 0x3F, 0x33, 0x00}, // U+00C5 (A ring)
|
||||||
|
{ 0x7C, 0x36, 0x33, 0x7F, 0x33, 0x33, 0x73, 0x00}, // U+00C6 (AE)
|
||||||
|
{ 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x18, 0x30, 0x1E}, // U+00C7 (C cedille)
|
||||||
|
{ 0x07, 0x00, 0x3F, 0x06, 0x1E, 0x06, 0x3F, 0x00}, // U+00C8 (E grave)
|
||||||
|
{ 0x38, 0x00, 0x3F, 0x06, 0x1E, 0x06, 0x3F, 0x00}, // U+00C9 (E aigu)
|
||||||
|
{ 0x0C, 0x12, 0x3F, 0x06, 0x1E, 0x06, 0x3F, 0x00}, // U+00CA (E circumflex)
|
||||||
|
{ 0x36, 0x00, 0x3F, 0x06, 0x1E, 0x06, 0x3F, 0x00}, // U+00CB (E umlaut)
|
||||||
|
{ 0x07, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+00CC (I grave)
|
||||||
|
{ 0x38, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+00CD (I aigu)
|
||||||
|
{ 0x0C, 0x12, 0x00, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+00CE (I circumflex)
|
||||||
|
{ 0x33, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+00CF (I umlaut)
|
||||||
|
{ 0x3F, 0x66, 0x6F, 0x6F, 0x66, 0x66, 0x3F, 0x00}, // U+00D0 (Eth)
|
||||||
|
{ 0x3F, 0x00, 0x33, 0x37, 0x3F, 0x3B, 0x33, 0x00}, // U+00D1 (N ~)
|
||||||
|
{ 0x0E, 0x00, 0x18, 0x3C, 0x66, 0x3C, 0x18, 0x00}, // U+00D2 (O grave)
|
||||||
|
{ 0x70, 0x00, 0x18, 0x3C, 0x66, 0x3C, 0x18, 0x00}, // U+00D3 (O aigu)
|
||||||
|
{ 0x3C, 0x66, 0x18, 0x3C, 0x66, 0x3C, 0x18, 0x00}, // U+00D4 (O circumflex)
|
||||||
|
{ 0x6E, 0x3B, 0x00, 0x3E, 0x63, 0x63, 0x3E, 0x00}, // U+00D5 (O ~)
|
||||||
|
{ 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00}, // U+00D6 (O umlaut)
|
||||||
|
{ 0x00, 0x36, 0x1C, 0x08, 0x1C, 0x36, 0x00, 0x00}, // U+00D7 (multiplicative x)
|
||||||
|
{ 0x5C, 0x36, 0x73, 0x7B, 0x6F, 0x36, 0x1D, 0x00}, // U+00D8 (O stroke)
|
||||||
|
{ 0x0E, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00}, // U+00D9 (U grave)
|
||||||
|
{ 0x70, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00}, // U+00DA (U aigu)
|
||||||
|
{ 0x3C, 0x66, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x00}, // U+00DB (U circumflex)
|
||||||
|
{ 0x33, 0x00, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+00DC (U umlaut)
|
||||||
|
{ 0x70, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x00}, // U+00DD (Y aigu)
|
||||||
|
{ 0x0F, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+00DE (Thorn)
|
||||||
|
{ 0x00, 0x1E, 0x33, 0x1F, 0x33, 0x1F, 0x03, 0x03}, // U+00DF (beta)
|
||||||
|
{ 0x07, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00}, // U+00E0 (a grave)
|
||||||
|
{ 0x38, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00}, // U+00E1 (a aigu)
|
||||||
|
{ 0x7E, 0xC3, 0x3C, 0x60, 0x7C, 0x66, 0xFC, 0x00}, // U+00E2 (a circumflex)
|
||||||
|
{ 0x6E, 0x3B, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00}, // U+00E3 (a ~)
|
||||||
|
{ 0x33, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00}, // U+00E4 (a umlaut)
|
||||||
|
{ 0x0C, 0x0C, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00}, // U+00E5 (a ring)
|
||||||
|
{ 0x00, 0x00, 0xFE, 0x30, 0xFE, 0x33, 0xFE, 0x00}, // U+00E6 (ae)
|
||||||
|
{ 0x00, 0x00, 0x1E, 0x03, 0x03, 0x1E, 0x30, 0x1C}, // U+00E7 (c cedille)
|
||||||
|
{ 0x07, 0x00, 0x1E, 0x33, 0x3F, 0x03, 0x1E, 0x00}, // U+00E8 (e grave)
|
||||||
|
{ 0x38, 0x00, 0x1E, 0x33, 0x3F, 0x03, 0x1E, 0x00}, // U+00E9 (e aigu)
|
||||||
|
{ 0x7E, 0xC3, 0x3C, 0x66, 0x7E, 0x06, 0x3C, 0x00}, // U+00EA (e circumflex)
|
||||||
|
{ 0x33, 0x00, 0x1E, 0x33, 0x3F, 0x03, 0x1E, 0x00}, // U+00EB (e umlaut)
|
||||||
|
{ 0x07, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+00EC (i grave)
|
||||||
|
{ 0x1C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+00ED (i augu)
|
||||||
|
{ 0x3E, 0x63, 0x1C, 0x18, 0x18, 0x18, 0x3C, 0x00}, // U+00EE (i circumflex)
|
||||||
|
{ 0x33, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+00EF (i umlaut)
|
||||||
|
{ 0x1B, 0x0E, 0x1B, 0x30, 0x3E, 0x33, 0x1E, 0x00}, // U+00F0 (eth)
|
||||||
|
{ 0x00, 0x1F, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x00}, // U+00F1 (n ~)
|
||||||
|
{ 0x00, 0x07, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+00F2 (o grave)
|
||||||
|
{ 0x00, 0x38, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+00F3 (o aigu)
|
||||||
|
{ 0x1E, 0x33, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+00F4 (o circumflex)
|
||||||
|
{ 0x6E, 0x3B, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+00F5 (o ~)
|
||||||
|
{ 0x00, 0x33, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+00F6 (o umlaut)
|
||||||
|
{ 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00}, // U+00F7 (division)
|
||||||
|
{ 0x00, 0x60, 0x3C, 0x76, 0x7E, 0x6E, 0x3C, 0x06}, // U+00F8 (o stroke)
|
||||||
|
{ 0x00, 0x07, 0x00, 0x33, 0x33, 0x33, 0x7E, 0x00}, // U+00F9 (u grave)
|
||||||
|
{ 0x00, 0x38, 0x00, 0x33, 0x33, 0x33, 0x7E, 0x00}, // U+00FA (u aigu)
|
||||||
|
{ 0x1E, 0x33, 0x00, 0x33, 0x33, 0x33, 0x7E, 0x00}, // U+00FB (u circumflex)
|
||||||
|
{ 0x00, 0x33, 0x00, 0x33, 0x33, 0x33, 0x7E, 0x00}, // U+00FC (u umlaut)
|
||||||
|
{ 0x00, 0x38, 0x00, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+00FD (y aigu)
|
||||||
|
{ 0x00, 0x00, 0x06, 0x3E, 0x66, 0x3E, 0x06, 0x00}, // U+00FE (thorn)
|
||||||
|
{ 0x00, 0x33, 0x00, 0x33, 0x33, 0x3E, 0x30, 0x1F} // U+00FF (y umlaut)
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned char bitfont_greek[58][8] = {
|
||||||
|
{ 0x2D, 0x00, 0x0C, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0390 (iota with tonos and diaeresis)
|
||||||
|
{ 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0391 (Alpha)
|
||||||
|
{ 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0392 (Beta)
|
||||||
|
{ 0x3F, 0x33, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00}, // U+0393 (Gamma)
|
||||||
|
{ 0x08, 0x1C, 0x1C, 0x36, 0x36, 0x63, 0x7F, 0x00}, // U+0394 (Delta)
|
||||||
|
{ 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0395 (Epsilon)
|
||||||
|
{ 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+0396 (Zeta)
|
||||||
|
{ 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0397 (Eta)
|
||||||
|
{ 0x1C, 0x36, 0x63, 0x7F, 0x63, 0x36, 0x1C, 0x00}, // U+0398 (Theta)
|
||||||
|
{ 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0399 (Iota)
|
||||||
|
{ 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+039A (Kappa)
|
||||||
|
{ 0x08, 0x1C, 0x1C, 0x36, 0x36, 0x63, 0x63, 0x00}, // U+039B (Lambda)
|
||||||
|
{ 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+039C (Mu)
|
||||||
|
{ 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+039D (Nu)
|
||||||
|
{ 0x7F, 0x63, 0x00, 0x3E, 0x00, 0x63, 0x7F, 0x00}, // U+039E (Xi)
|
||||||
|
{ 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+039F (Omikron)
|
||||||
|
{ 0x7F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00}, // U+03A0 (Pi)
|
||||||
|
{ 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+03A1 (Rho)
|
||||||
|
{ 0x00, 0x01, 0x02, 0x04, 0x4F, 0x90, 0xA0, 0x40}, // U+03A2
|
||||||
|
{ 0x7F, 0x63, 0x06, 0x0C, 0x06, 0x63, 0x7F, 0x00}, // U+03A3 (Sigma 2)
|
||||||
|
{ 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+03A4 (Tau)
|
||||||
|
{ 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+03A5 (Upsilon)
|
||||||
|
{ 0x18, 0x7E, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x00}, // U+03A6 (Phi)
|
||||||
|
{ 0x63, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x63, 0x00}, // U+03A7 (Chi)
|
||||||
|
{ 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x3C, 0x00}, // U+03A8 (Psi)
|
||||||
|
{ 0x3E, 0x63, 0x63, 0x63, 0x36, 0x36, 0x77, 0x00}, // U+03A9 (Omega)
|
||||||
|
{ 0x33, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0399 (Iota with diaeresis)
|
||||||
|
{ 0x33, 0x00, 0x33, 0x33, 0x1E, 0x0C, 0x1E, 0x00}, // U+03A5 (Upsilon with diaeresis)
|
||||||
|
{ 0x70, 0x00, 0x6E, 0x3B, 0x13, 0x3B, 0x6E, 0x00}, // U+03AC (alpha aigu)
|
||||||
|
{ 0x38, 0x00, 0x1E, 0x03, 0x0E, 0x03, 0x1E, 0x00}, // U+03AD (epsilon aigu)
|
||||||
|
{ 0x38, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x30}, // U+03AE (eta aigu)
|
||||||
|
{ 0x38, 0x00, 0x0C, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+03AF (iota aigu)
|
||||||
|
{ 0x2D, 0x00, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+03B0 (upsilon with tonos and diaeresis)
|
||||||
|
{ 0x00, 0x00, 0x6E, 0x3B, 0x13, 0x3B, 0x6E, 0x00}, // U+03B1 (alpha)
|
||||||
|
{ 0x00, 0x1E, 0x33, 0x1F, 0x33, 0x1F, 0x03, 0x03}, // U+03B2 (beta)
|
||||||
|
{ 0x00, 0x00, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x00}, // U+03B3 (gamma)
|
||||||
|
{ 0x38, 0x0C, 0x18, 0x3E, 0x33, 0x33, 0x1E, 0x00}, // U+03B4 (delta)
|
||||||
|
{ 0x00, 0x00, 0x1E, 0x03, 0x0E, 0x03, 0x1E, 0x00}, // U+03B5 (epsilon)
|
||||||
|
{ 0x00, 0x3F, 0x06, 0x03, 0x03, 0x1E, 0x30, 0x1C}, // U+03B6 (zeta)
|
||||||
|
{ 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x30}, // U+03B7 (eta)
|
||||||
|
{ 0x00, 0x00, 0x1E, 0x33, 0x3F, 0x33, 0x1E, 0x00}, // U+03B8 (theta)
|
||||||
|
{ 0x00, 0x00, 0x0C, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+03B9 (iota)
|
||||||
|
{ 0x00, 0x00, 0x33, 0x1B, 0x0F, 0x1B, 0x33, 0x00}, // U+03BA (kappa)
|
||||||
|
{ 0x00, 0x03, 0x06, 0x0C, 0x1C, 0x36, 0x63, 0x00}, // U+03BB (lambda)
|
||||||
|
{ 0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x03}, // U+03BC (mu)
|
||||||
|
{ 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+03BD (nu)
|
||||||
|
{ 0x1E, 0x03, 0x0E, 0x03, 0x03, 0x1E, 0x30, 0x1C}, // U+03BE (xi)
|
||||||
|
{ 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+03BF (omikron)
|
||||||
|
{ 0x00, 0x00, 0x7F, 0x36, 0x36, 0x36, 0x36, 0x00}, // U+03C0 (pi)
|
||||||
|
{ 0x00, 0x00, 0x3C, 0x66, 0x66, 0x36, 0x06, 0x06}, // U+03C1 (rho)
|
||||||
|
{ 0x00, 0x00, 0x3E, 0x03, 0x03, 0x1E, 0x30, 0x1C}, // U+03C2 (sigma 1)
|
||||||
|
{ 0x00, 0x00, 0x7E, 0x1B, 0x1B, 0x1B, 0x0E, 0x00}, // U+03C3 (sigma 2)
|
||||||
|
{ 0x00, 0x00, 0x7E, 0x18, 0x18, 0x58, 0x30, 0x00}, // U+03C4 (tau)
|
||||||
|
{ 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+03C5 (upsilon)
|
||||||
|
{ 0x00, 0x00, 0x76, 0xDB, 0xDB, 0x7E, 0x18, 0x00}, // U+03C6 (phi)
|
||||||
|
{ 0x00, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+03C7 (chi)
|
||||||
|
{ 0x00, 0x00, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x00}, // U+03C8 (psi)
|
||||||
|
{ 0x00, 0x00, 0x36, 0x63, 0x6B, 0x7F, 0x36, 0x00} // U+03C9 (omega)
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned char bitfont_box[128][8] = {
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00}, // U+2500 (thin horizontal)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00}, // U+2501 (thick horizontal)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}, // U+2502 (thin vertical)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, // U+2503 (thich vertical)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00}, // U+2504 (thin horizontal dashed)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xBB, 0xBB, 0x00, 0x00, 0x00}, // U+2505 (thick horizontal dashed)
|
||||||
|
{ 0x08, 0x00, 0x08, 0x08, 0x08, 0x00, 0x08, 0x08}, // U+2506 (thin vertical dashed)
|
||||||
|
{ 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18}, // U+2507 (thich vertical dashed)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00}, // U+2508 (thin horizontal dotted)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00}, // U+2509 (thick horizontal dotted)
|
||||||
|
{ 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08}, // U+250A (thin vertical dotted)
|
||||||
|
{ 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18}, // U+250B (thich vertical dotted)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08}, // U+250C (down L, right L)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x08, 0x08, 0x08}, // U+250D (down L, right H)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18}, // U+250E (down H, right L)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18}, // U+250F (down H, right H)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x08, 0x08}, // U+2510 (down L, left L)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x08, 0x08, 0x08}, // U+2511 (down L, left H)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18}, // U+2512 (down H, left L)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18}, // U+2513 (down H, left H)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x00, 0x00, 0x00}, // U+2514 (up L, right L)
|
||||||
|
{ 0x08, 0x08, 0x08, 0xf8, 0xf8, 0x00, 0x00, 0x00}, // U+2515 (up L, right H)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00}, // U+2516 (up H, right L)
|
||||||
|
{ 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00}, // U+2517 (up H, right H)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x08, 0x0f, 0x00, 0x00, 0x00}, // U+2518 (up L, left L)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x0f, 0x0f, 0x00, 0x00, 0x00}, // U+2519 (up L, left H)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00}, // U+251A (up H, left L)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00}, // U+251B (up H, left H)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x08, 0x08}, // U+251C (down L, right L, up L)
|
||||||
|
{ 0x08, 0x08, 0x08, 0xf8, 0xf8, 0x08, 0x08, 0x08}, // U+251D (down L, right H, up L)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x18, 0xf8, 0x08, 0x08, 0x08}, // U+251E (down L, right L, up H)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x18, 0x18, 0x18}, // U+251F (down H, right L, up L)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18}, // U+2520 (down H, right L, up H)
|
||||||
|
{ 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x08, 0x08, 0x08}, // U+2521 (down L, right H, up H)
|
||||||
|
{ 0x08, 0x08, 0x08, 0xf8, 0xf8, 0x18, 0x18, 0x18}, // U+2522 (down H, right H, up L)
|
||||||
|
{ 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18}, // U+2523 (down H, right H, up H)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08}, // U+2524 (down L, left L, up L)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x0f, 0x0f, 0x08, 0x08, 0x08}, // U+2525 (down L, left H, up L)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x18, 0x1f, 0x08, 0x08, 0x08}, // U+2526 (down L, left L, up H)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x08, 0x1f, 0x18, 0x18, 0x18}, // U+2527 (down H, left L, up L)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18}, // U+2528 (down H, left L, up H)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x08, 0x08, 0x08}, // U+2529 (down L, left H, up H)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x1f, 0x1f, 0x18, 0x18, 0x18}, // U+252A (down H, left H, up L)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18}, // U+252B (down H, left H, up H)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0xff, 0x08, 0x08, 0x08}, // U+252C (down L, right L, left L)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x0f, 0xff, 0x08, 0x08, 0x08}, // U+252D (down L, right L, left H)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xf8, 0xff, 0x08, 0x08, 0x08}, // U+252E (down L, right H, left L)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xff, 0xff, 0x08, 0x08, 0x08}, // U+252F (down L, right H, left H)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18}, // U+2530 (down H, right L, left L)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x1f, 0xff, 0x18, 0x18, 0x18}, // U+2531 (down H, right L, left H)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xf8, 0xff, 0x18, 0x18, 0x18}, // U+2532 (down H, right H, left L)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18}, // U+2533 (down H, right H, left H)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x08, 0xff, 0x00, 0x00, 0x00}, // U+2534 (up L, right L, left L)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x0f, 0xff, 0x00, 0x00, 0x00}, // U+2535 (up L, right L, left H)
|
||||||
|
{ 0x08, 0x08, 0x08, 0xf8, 0xff, 0x00, 0x00, 0x00}, // U+2536 (up L, right H, left L)
|
||||||
|
{ 0x08, 0x08, 0x08, 0xff, 0xff, 0x00, 0x00, 0x00}, // U+2537 (up L, right H, left H)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00}, // U+2538 (up H, right L, left L)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x1f, 0xff, 0x00, 0x00, 0x00}, // U+2539 (up H, right L, left H)
|
||||||
|
{ 0x18, 0x18, 0x18, 0xf8, 0xff, 0x00, 0x00, 0x00}, // U+253A (up H, right H, left L)
|
||||||
|
{ 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00}, // U+253B (up H, right H, left H)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08}, // U+253C (up L, right L, left L, down L)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x0f, 0xff, 0x08, 0x08, 0x08}, // U+253D (up L, right L, left H, down L)
|
||||||
|
{ 0x08, 0x08, 0x08, 0xf8, 0xff, 0x08, 0x08, 0x08}, // U+253E (up L, right H, left L, down L)
|
||||||
|
{ 0x08, 0x08, 0x08, 0xff, 0xff, 0x08, 0x08, 0x08}, // U+253F (up L, right H, left H, down L)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x18, 0xff, 0x08, 0x08, 0x08}, // U+2540 (up H, right L, left L, down L)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x08, 0xff, 0x18, 0x18, 0x18}, // U+2541 (up L, right L, left L, down H)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18}, // U+2542 (up H, right L, left L, down H)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x1f, 0xff, 0x08, 0x08, 0x08}, // U+2543 (up H, right L, left H, down L)
|
||||||
|
{ 0x18, 0x18, 0x18, 0xf8, 0xff, 0x08, 0x08, 0x08}, // U+2544 (up H, right H, left L, down L)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x1f, 0xff, 0x18, 0x18, 0x18}, // U+2545 (up L, right L, left H, down H)
|
||||||
|
{ 0x08, 0x08, 0x08, 0xf8, 0xff, 0x18, 0x18, 0x18}, // U+2546 (up L, right H, left L, down H)
|
||||||
|
{ 0x08, 0x08, 0x08, 0xff, 0xff, 0x18, 0x18, 0x18}, // U+2547 (up L, right H, left H, down H)
|
||||||
|
{ 0x18, 0x18, 0x18, 0xff, 0xff, 0x08, 0x08, 0x08}, // U+254B (up H, right H, left H, down L)
|
||||||
|
{ 0x18, 0x18, 0x18, 0xf8, 0xff, 0x18, 0x18, 0x18}, // U+254A (up H, right H, left L, down H)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x1f, 0xff, 0x18, 0x18, 0x18}, // U+2549 (up H, right L, left H, down H)
|
||||||
|
{ 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18}, // U+254B (up H, right H, left H, down H)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0xE7, 0x00, 0x00, 0x00}, // U+254C (thin horizontal broken)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xE7, 0xE7, 0x00, 0x00, 0x00}, // U+254D (thick horizontal broken)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x08}, // U+254E (thin vertical broken)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18}, // U+254F (thich vertical broken)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00}, // U+2550 (double horizontal)
|
||||||
|
{ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14}, // U+2551 (double vertical)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xF8, 0x08, 0xF8, 0x08, 0x08}, // U+2552 (down L, right D)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0xFC, 0x14, 0x14, 0x14}, // U+2553 (down D, right L)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xFC, 0x04, 0xF4, 0x14, 0x14}, // U+2554 (down D, right D)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x0F, 0x08, 0x0F, 0x08, 0x08}, // U+2555 (down L, left D)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x14, 0x14, 0x14}, // U+2556 (down D, left L)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x1F, 0x10, 0x17, 0x14, 0x14}, // U+2557 (down D, left D)
|
||||||
|
{ 0x08, 0x08, 0x08, 0xF8, 0x08, 0xF8, 0x00, 0x00}, // U+2558 (up L, right D)
|
||||||
|
{ 0x14, 0x14, 0x14, 0x14, 0xFC, 0x00, 0x00, 0x00}, // U+2559 (up D, right L)
|
||||||
|
{ 0x14, 0x14, 0x14, 0xF4, 0x04, 0xFC, 0x00, 0x00}, // U+255A (up D, right D)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x0F, 0x08, 0x0F, 0x00, 0x00}, // U+255B (up L, left D)
|
||||||
|
{ 0x14, 0x14, 0x14, 0x14, 0x1F, 0x00, 0x00, 0x00}, // U+255C (up D, left L)
|
||||||
|
{ 0x14, 0x14, 0x14, 0x17, 0x10, 0x1F, 0x00, 0x00}, // U+255D (up D, left D)
|
||||||
|
{ 0x08, 0x08, 0x08, 0xF8, 0x08, 0xF8, 0x08, 0x08}, // U+255E (up L, down L, right D)
|
||||||
|
{ 0x14, 0x14, 0x14, 0x14, 0xF4, 0x14, 0x14, 0x14}, // U+255F (up D, down D, right L)
|
||||||
|
{ 0x14, 0x14, 0x14, 0xF4, 0x04, 0xF4, 0x14, 0x14}, // U+2560 (up D, down D, right D)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x0F, 0x08, 0x0F, 0x08, 0x08}, // U+2561 (up L, down L, left D)
|
||||||
|
{ 0x14, 0x14, 0x14, 0x14, 0x17, 0x14, 0x14, 0x14}, // U+2562 (up D, down D, left L)
|
||||||
|
{ 0x14, 0x14, 0x14, 0x17, 0x10, 0x17, 0x14, 0x14}, // U+2563 (up D, down D, left D)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x08, 0x08}, // U+2564 (left D, right D, down L)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0x14, 0x14, 0x14}, // U+2565 (left L, right L, down D)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x14, 0x14}, // U+2566 (left D, right D, down D)
|
||||||
|
{ 0x08, 0x08, 0x08, 0xFF, 0x00, 0xFF, 0x00, 0x00}, // U+2567 (left D, right D, up L)
|
||||||
|
{ 0x14, 0x14, 0x14, 0x14, 0xFF, 0x00, 0x00, 0x00}, // U+2568 (left L, right L, up D)
|
||||||
|
{ 0x14, 0x14, 0x14, 0xF7, 0x00, 0xFF, 0x00, 0x00}, // U+2569 (left D, right D, up D)
|
||||||
|
{ 0x08, 0x08, 0x08, 0xFF, 0x08, 0xFF, 0x08, 0x08}, // U+256A (left D, right D, down L, up L)
|
||||||
|
{ 0x14, 0x14, 0x14, 0x14, 0xFF, 0x14, 0x14, 0x14}, // U+256B (left L, right L, down D, up D)
|
||||||
|
{ 0x14, 0x14, 0x14, 0xF7, 0x00, 0xF7, 0x14, 0x14}, // U+256C (left D, right D, down D, up D)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x08, 0x08}, // U+256D (curve down-right)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x08, 0x08}, // U+256E (curve down-left)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00}, // U+256F (curve up-left)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00}, // U+2570 (curve up-right)
|
||||||
|
{ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}, // U+2571 (diagonal bottom-left to top-right)
|
||||||
|
{ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}, // U+2572 (diagonal bottom-right to top-left)
|
||||||
|
{ 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81}, // U+2573 (diagonal cross)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00}, // U+2574 (left L)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00}, // U+2575 (up L)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00}, // U+2576 (right L)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08}, // U+2577 (down L)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00}, // U+2578 (left H)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}, // U+2579 (up H)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0x00}, // U+257A (right H)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18}, // U+257B (down H)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x00}, // U+257C (right H, left L)
|
||||||
|
{ 0x08, 0x08, 0x08, 0x08, 0x18, 0x18, 0x18, 0x18}, // U+257D (up L, down H)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00}, // U+257E (right L, left H)
|
||||||
|
{ 0x18, 0x18, 0x18, 0x18, 0x08, 0x08, 0x08, 0x08} // U+257F (up H, down L)
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned char bitfont_block[32][8] = {
|
||||||
|
{ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}, // U+2580 (top half)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+2581 (box 1/8)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF}, // U+2582 (box 2/8)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF}, // U+2583 (box 3/8)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}, // U+2584 (bottom half)
|
||||||
|
{ 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // U+2585 (box 5/8)
|
||||||
|
{ 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // U+2586 (box 6/8)
|
||||||
|
{ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // U+2587 (box 7/8)
|
||||||
|
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, // U+2588 (solid)
|
||||||
|
{ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F}, // U+2589 (box 7/8)
|
||||||
|
{ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F}, // U+258A (box 6/8)
|
||||||
|
{ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F}, // U+258B (box 5/8)
|
||||||
|
{ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F}, // U+258C (left half)
|
||||||
|
{ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}, // U+258D (box 3/8)
|
||||||
|
{ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}, // U+258E (box 2/8)
|
||||||
|
{ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, // U+258F (box 1/8)
|
||||||
|
{ 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0}, // U+2590 (right half)
|
||||||
|
{ 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00}, // U+2591 (25% solid)
|
||||||
|
{ 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA}, // U+2592 (50% solid)
|
||||||
|
{ 0xFF, 0xAA, 0xFF, 0x55, 0xFF, 0xAA, 0xFF, 0x55}, // U+2593 (75% solid)
|
||||||
|
{ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+2594 (box 1/8)
|
||||||
|
{ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}, // U+2595 (box 1/8)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F}, // U+2596 (box bottom left)
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0}, // U+2597 (box bottom right)
|
||||||
|
{ 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00}, // U+2598 (box top left)
|
||||||
|
{ 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF}, // U+2599 (boxes left and bottom)
|
||||||
|
{ 0x0F, 0x0F, 0x0F, 0x0F, 0xF0, 0xF0, 0xF0, 0xF0}, // U+259A (boxes top-left and bottom right)
|
||||||
|
{ 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F}, // U+259B (boxes top and left)
|
||||||
|
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0}, // U+259C (boxes top and right)
|
||||||
|
{ 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00}, // U+259D (box top right)
|
||||||
|
{ 0xF0, 0xF0, 0xF0, 0xF0, 0x0F, 0x0F, 0x0F, 0x0F}, // U+259E (boxes top right and bottom left)
|
||||||
|
{ 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF}, // U+259F (boxes right and bottom)
|
||||||
|
};
|
20
chroma/kernel.c
Normal file
20
chroma/kernel.c
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include <kernel/chroma.h>
|
||||||
|
|
||||||
|
|
||||||
|
void _start(void) {
|
||||||
|
|
||||||
|
SerialPrintf("\r\nBooting Chroma..\r\n");
|
||||||
|
InitPrint();
|
||||||
|
|
||||||
|
SetupInitialGDT();
|
||||||
|
SetupIDT();
|
||||||
|
InitInterrupts();
|
||||||
|
|
||||||
|
InitMemoryManager();
|
||||||
|
MemoryTest();
|
||||||
|
|
||||||
|
InitPaging();
|
||||||
|
|
||||||
|
for(;;) { }
|
||||||
|
|
||||||
|
}
|
202
chroma/system/cpu.c
Normal file
202
chroma/system/cpu.c
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
#include <kernel/chroma.h>
|
||||||
|
#include <kernel/system/interrupts.h>
|
||||||
|
|
||||||
|
#define NMI_STACK 4096
|
||||||
|
#define DF_STACK 4096
|
||||||
|
#define MC_STACK 4096
|
||||||
|
#define BP_STACK 4096
|
||||||
|
|
||||||
|
__attribute__((aligned(64))) static volatile unsigned char NMIStack[NMI_STACK] = {0};
|
||||||
|
__attribute__((aligned(64))) static volatile unsigned char DFStack[DF_STACK] = {0};
|
||||||
|
__attribute__((aligned(64))) static volatile unsigned char MCStack[MC_STACK] = {0};
|
||||||
|
__attribute__((aligned(64))) static volatile unsigned char BPStack[BP_STACK] = {0};
|
||||||
|
|
||||||
|
__attribute__((aligned(64))) static volatile size_t InitGDT[5] = {
|
||||||
|
0,
|
||||||
|
0x00af9a000000ffff,
|
||||||
|
0x00cf92000000ffff,
|
||||||
|
0x0080890000000067,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
__attribute__((aligned(64))) static volatile TSS64 TSSEntries = {0};
|
||||||
|
|
||||||
|
__attribute__((aligned(64))) static volatile IDT_GATE IDTEntries[256] = {0};
|
||||||
|
|
||||||
|
static void RefreshCS() {
|
||||||
|
|
||||||
|
__asm__ __volatile__ ("mov $16, %ax \n\t" // 16 = 0x10 = index 2 of GDT
|
||||||
|
"mov %ax, %ds \n\t" // Next few lines prepare the processor for the sudden change into the data segment
|
||||||
|
"mov %ax, %es \n\t" //
|
||||||
|
"mov %ax, %fs \n\t" //
|
||||||
|
"mov %ax, %gs \n\t" //
|
||||||
|
"mov %ax, %ss \n\t" //
|
||||||
|
"movq $8, %rdx \n\t" // 8 = 0x8 = index 1 of GDT
|
||||||
|
"leaq 4(%rip), %rax \n\t" // Returns execution to immediately after the iret, required for changing %cs while in long mode. - this is currently literally the only way to do it.
|
||||||
|
"pushq %rdx \n\t" //
|
||||||
|
"pushq %rax \n\t" //
|
||||||
|
"lretq \n\t"); //
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SetupInitialGDT() {
|
||||||
|
DESC_TBL GDTData = {0};
|
||||||
|
size_t TSSBase = (uint64_t) (&TSSEntries);
|
||||||
|
|
||||||
|
uint16_t TSSLower = (uint16_t) TSSBase;
|
||||||
|
uint8_t TSSMid1 = (uint8_t) (TSSBase >> 16);
|
||||||
|
uint8_t TSSMid2 = (uint8_t) (TSSBase >> 24);
|
||||||
|
uint32_t TSSHigher = (uint32_t) (TSSBase >> 32);
|
||||||
|
|
||||||
|
GDTData.Limit = sizeof(InitGDT) - 1;
|
||||||
|
GDTData.Base = (size_t) InitGDT;
|
||||||
|
|
||||||
|
( (TSS_ENTRY*) (&((GDT_ENTRY*) InitGDT)[3]) )->BaseLow = TSSLower;
|
||||||
|
( (TSS_ENTRY*) (&((GDT_ENTRY*) InitGDT)[3]) )->BaseMid1 = TSSMid1;
|
||||||
|
( (TSS_ENTRY*) (&((GDT_ENTRY*) InitGDT)[3]) )->BaseMid2 = TSSMid2;
|
||||||
|
( (TSS_ENTRY*) (&((GDT_ENTRY*) InitGDT)[3]) )->BaseHigh = TSSHigher;
|
||||||
|
|
||||||
|
WriteGDT(GDTData);
|
||||||
|
WriteTSR(3 << 3);
|
||||||
|
RefreshCS();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetISR(size_t ISRNum, size_t ISRAddr) {
|
||||||
|
uint16_t ISRBaseLow = (uint16_t) ISRAddr;
|
||||||
|
uint16_t ISRBaseMid = (uint16_t) (ISRAddr >> 16);
|
||||||
|
uint32_t ISRBaseHigh = (uint32_t) (ISRAddr >> 32);
|
||||||
|
|
||||||
|
IDTEntries[ISRNum].BaseLow = ISRBaseLow;
|
||||||
|
IDTEntries[ISRNum].Segment = 0x08;
|
||||||
|
IDTEntries[ISRNum].ISTAndZero = 0;
|
||||||
|
IDTEntries[ISRNum].SegmentType = 0x8E;
|
||||||
|
IDTEntries[ISRNum].BaseMid = ISRBaseMid;
|
||||||
|
IDTEntries[ISRNum].BaseHigh = ISRBaseHigh;
|
||||||
|
IDTEntries[ISRNum].Reserved = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetISRNMI(size_t ISRNum, size_t ISRAddr) {
|
||||||
|
uint16_t ISRBaseLow = (uint16_t) ISRAddr;
|
||||||
|
uint16_t ISRBaseMid = (uint16_t) (ISRAddr >> 16);
|
||||||
|
uint32_t ISRBaseHigh = (uint32_t) (ISRAddr >> 32);
|
||||||
|
|
||||||
|
IDTEntries[ISRNum].BaseLow = ISRBaseLow;
|
||||||
|
IDTEntries[ISRNum].Segment = 0x08;
|
||||||
|
IDTEntries[ISRNum].ISTAndZero = 1;
|
||||||
|
IDTEntries[ISRNum].SegmentType = 0x8E;
|
||||||
|
IDTEntries[ISRNum].BaseMid = ISRBaseMid;
|
||||||
|
IDTEntries[ISRNum].BaseHigh = ISRBaseHigh;
|
||||||
|
IDTEntries[ISRNum].Reserved = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetISRDF(size_t ISRNum, size_t ISRAddr) {
|
||||||
|
uint16_t ISRBaseLow = (uint16_t) ISRAddr;
|
||||||
|
uint16_t ISRBaseMid = (uint16_t) (ISRAddr >> 16);
|
||||||
|
uint32_t ISRBaseHigh = (uint32_t) (ISRAddr >> 32);
|
||||||
|
|
||||||
|
IDTEntries[ISRNum].BaseLow = ISRBaseLow;
|
||||||
|
IDTEntries[ISRNum].Segment = 0x08;
|
||||||
|
IDTEntries[ISRNum].ISTAndZero = 2;
|
||||||
|
IDTEntries[ISRNum].SegmentType = 0x8E;
|
||||||
|
IDTEntries[ISRNum].BaseMid = ISRBaseMid;
|
||||||
|
IDTEntries[ISRNum].BaseHigh = ISRBaseHigh;
|
||||||
|
IDTEntries[ISRNum].Reserved = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetISRMC(size_t ISRNum, size_t ISRAddr) {
|
||||||
|
uint16_t ISRBaseLow = (uint16_t) ISRAddr;
|
||||||
|
uint16_t ISRBaseMid = (uint16_t) (ISRAddr >> 16);
|
||||||
|
uint32_t ISRBaseHigh = (uint32_t) (ISRAddr >> 32);
|
||||||
|
|
||||||
|
IDTEntries[ISRNum].BaseLow = ISRBaseLow;
|
||||||
|
IDTEntries[ISRNum].Segment = 0x08;
|
||||||
|
IDTEntries[ISRNum].ISTAndZero = 3;
|
||||||
|
IDTEntries[ISRNum].SegmentType = 0x8E;
|
||||||
|
IDTEntries[ISRNum].BaseMid = ISRBaseMid;
|
||||||
|
IDTEntries[ISRNum].BaseHigh = ISRBaseHigh;
|
||||||
|
IDTEntries[ISRNum].Reserved = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetISRBP(size_t ISRNum, size_t ISRAddr) {
|
||||||
|
uint16_t ISRBaseLow = (uint16_t) ISRAddr;
|
||||||
|
uint16_t ISRBaseMid = (uint16_t) (ISRAddr >> 16);
|
||||||
|
uint32_t ISRBaseHigh = (uint32_t) (ISRAddr >> 32);
|
||||||
|
|
||||||
|
IDTEntries[ISRNum].BaseLow = ISRBaseLow;
|
||||||
|
IDTEntries[ISRNum].Segment = 0x08;
|
||||||
|
IDTEntries[ISRNum].ISTAndZero = 4;
|
||||||
|
IDTEntries[ISRNum].SegmentType = 0x8E;
|
||||||
|
IDTEntries[ISRNum].BaseMid = ISRBaseMid;
|
||||||
|
IDTEntries[ISRNum].BaseHigh = ISRBaseHigh;
|
||||||
|
IDTEntries[ISRNum].Reserved = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupIDT() {
|
||||||
|
DESC_TBL IDTData = {0};
|
||||||
|
IDTData.Limit = (sizeof(IDT_GATE) * 256) - 1;
|
||||||
|
IDTData.Base = (size_t) &IDTEntries;
|
||||||
|
|
||||||
|
//memset(&IDTEntries, 0, sizeof(IDT_GATE) * 256);
|
||||||
|
|
||||||
|
RemapIRQControllers();
|
||||||
|
|
||||||
|
*(size_t*) (&TSSEntries.IST1) = (size_t) (NMIStack + NMI_STACK);
|
||||||
|
*(size_t*) (&TSSEntries.IST2) = (size_t) (DFStack + DF_STACK);
|
||||||
|
*(size_t*) (&TSSEntries.IST3) = (size_t) (MCStack + MC_STACK);
|
||||||
|
*(size_t*) (&TSSEntries.IST4) = (size_t) (BPStack + BP_STACK);
|
||||||
|
|
||||||
|
SetISR (0, (size_t) ISR0Handler);
|
||||||
|
SetISRBP (1, (size_t) ISR1Handler);
|
||||||
|
SetISRNMI (2, (size_t) ISR2Handler);
|
||||||
|
SetISRBP (3, (size_t) ISR3Handler);
|
||||||
|
SetISR (4, (size_t) ISR4Handler);
|
||||||
|
SetISR (5, (size_t) ISR5Handler);
|
||||||
|
SetISR (6, (size_t) ISR6Handler);
|
||||||
|
SetISR (7, (size_t) ISR7Handler);
|
||||||
|
SetISRDF (8, (size_t) ISR8Handler);
|
||||||
|
SetISR (9, (size_t) ISR9Handler);
|
||||||
|
SetISR (10, (size_t) ISR10Handler);
|
||||||
|
SetISR (11, (size_t) ISR11Handler);
|
||||||
|
SetISR (12, (size_t) ISR12Handler);
|
||||||
|
SetISR (13, (size_t) ISR13Handler);
|
||||||
|
SetISR (14, (size_t) ISR14Handler);
|
||||||
|
SetISR (15, (size_t) ISR15Handler);
|
||||||
|
SetISR (16, (size_t) ISR16Handler);
|
||||||
|
SetISR (17, (size_t) ISR17Handler);
|
||||||
|
SetISRMC (18, (size_t) ISR18Handler);
|
||||||
|
SetISR (19, (size_t) ISR19Handler);
|
||||||
|
SetISR (20, (size_t) ISR20Handler);
|
||||||
|
SetISR (30, (size_t) ISR30Handler);
|
||||||
|
|
||||||
|
for(size_t i = 1; i < 11; i++) {
|
||||||
|
if(i != 9) {
|
||||||
|
SetISR(i + 20, (size_t) ReservedISRHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetISR(32, (size_t) IRQ0Handler);
|
||||||
|
SetISR(33, (size_t) IRQ1Handler);
|
||||||
|
SetISR(34, (size_t) IRQ2Handler);
|
||||||
|
SetISR(35, (size_t) IRQ3Handler);
|
||||||
|
SetISR(36, (size_t) IRQ4Handler);
|
||||||
|
SetISR(37, (size_t) IRQ5Handler);
|
||||||
|
SetISR(38, (size_t) IRQ6Handler);
|
||||||
|
SetISR(39, (size_t) IRQ7Handler);
|
||||||
|
SetISR(40, (size_t) IRQ8Handler);
|
||||||
|
SetISR(41, (size_t) IRQ9Handler);
|
||||||
|
SetISR(42, (size_t) IRQ10Handler);
|
||||||
|
SetISR(43, (size_t) IRQ11Handler);
|
||||||
|
SetISR(44, (size_t) IRQ12Handler);
|
||||||
|
SetISR(45, (size_t) IRQ13Handler);
|
||||||
|
SetISR(46, (size_t) IRQ14Handler);
|
||||||
|
SetISR(47, (size_t) IRQ15Handler);
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: ISRs 32 to 256
|
||||||
|
|
||||||
|
WriteIDT(IDTData);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
115
chroma/system/drivers/keyboard.c
Normal file
115
chroma/system/drivers/keyboard.c
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
#include <kernel/chroma.h>
|
||||||
|
|
||||||
|
char keys[128] = {
|
||||||
|
0, 27,
|
||||||
|
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',
|
||||||
|
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',
|
||||||
|
0,
|
||||||
|
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '#',
|
||||||
|
0,
|
||||||
|
'\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/',
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void UpdateKeyboard(uint8_t msg) {
|
||||||
|
|
||||||
|
InputBuffer[0] = msg;
|
||||||
|
|
||||||
|
switch(msg) {
|
||||||
|
case 0x0:
|
||||||
|
KbdFlags.Error = 1;
|
||||||
|
//ResendBuffer();
|
||||||
|
break;
|
||||||
|
case 0xAA:
|
||||||
|
KbdFlags.SelfTest = 1;
|
||||||
|
break;
|
||||||
|
case 0xEE:
|
||||||
|
KbdFlags.Echo = 0;
|
||||||
|
KbdFlags.EchoCount = 2;
|
||||||
|
KbdEcho();
|
||||||
|
break;
|
||||||
|
case 0xFA:
|
||||||
|
KbdFlags.ACK = 1;
|
||||||
|
//ProgressBuffer();
|
||||||
|
break;
|
||||||
|
case 0xFC:
|
||||||
|
case 0xFD:
|
||||||
|
KbdFlags.SelfTest = 0;
|
||||||
|
KbdFlags.Error = 1;
|
||||||
|
//RestartKbd();
|
||||||
|
break;
|
||||||
|
case 0xFE:
|
||||||
|
//ResendBuffer();
|
||||||
|
break;
|
||||||
|
case 0xFF:
|
||||||
|
KbdFlags.Error = 1;
|
||||||
|
//ResendBuffer();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(msg & 0x80) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
SerialPrintf("Key pressed %c\r\n", keys[msg]);
|
||||||
|
WriteChar(keys[msg]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void KbdEcho() {
|
||||||
|
if(!KbdFlags.EchoCount) {
|
||||||
|
if(!KbdFlags.Echo) {
|
||||||
|
Send8042(0xEE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
KbdFlags.EchoCount = 0;
|
||||||
|
KbdFlags.Echo = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Send8042(size_t info) {
|
||||||
|
for(size_t i = 0; i < 8; i++) {
|
||||||
|
unsigned char chr = (unsigned char) info;
|
||||||
|
if(chr != 0) {
|
||||||
|
WritePort(0x60, chr, 1);
|
||||||
|
WaitFor8042();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaitFor8042() {
|
||||||
|
|
||||||
|
bool full = true;
|
||||||
|
while(full) {
|
||||||
|
full = ReadPort(0x64, 1) & 1;
|
||||||
|
}
|
||||||
|
}
|
378
chroma/system/interrupts.c
Normal file
378
chroma/system/interrupts.c
Normal file
|
@ -0,0 +1,378 @@
|
||||||
|
/************************
|
||||||
|
*** Team Kitty, 2019 ***
|
||||||
|
*** Sync ***
|
||||||
|
***********************/
|
||||||
|
|
||||||
|
/* This file contains all of the ISR and IRQ
|
||||||
|
* (Interrupt Service Request) functions.
|
||||||
|
*
|
||||||
|
* As they use the GCC interrupt attribute,
|
||||||
|
* this file must be compiled without red-
|
||||||
|
* zone protection, thus all of these
|
||||||
|
* functions are in their own file to
|
||||||
|
* accomodate this.
|
||||||
|
*
|
||||||
|
* Additionally, the kernel now has SSE/AVX support.
|
||||||
|
* So this file and this file *alone* must be compiled with
|
||||||
|
* -mgeneral-regs-only
|
||||||
|
*
|
||||||
|
* Calling a function like so:
|
||||||
|
*
|
||||||
|
* __attribute__((interrupt)) isr1(registers_t* frame) {}
|
||||||
|
*
|
||||||
|
* allows the function to be used to serve
|
||||||
|
* interrupts - GCC compiles it under unique
|
||||||
|
* conditions, as it preserves the state of
|
||||||
|
* the processor and stack between execution,
|
||||||
|
* as well as using the IRET instruction to
|
||||||
|
* return to the middle of the previous function.
|
||||||
|
*
|
||||||
|
* There is also a version of the interrupt
|
||||||
|
* attribute which allows for error handlers,
|
||||||
|
* these having a size_t input as an error code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kernel/chroma.h>
|
||||||
|
#include <kernel/system/interrupts.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef unsigned long long int uword_t;
|
||||||
|
|
||||||
|
/* All of the ISR routines call this function for now.
|
||||||
|
! This function is NOT leaf, and it might clobber the stack.
|
||||||
|
! Be careful!
|
||||||
|
*/
|
||||||
|
void ISR_Common(INTERRUPT_FRAME* Frame, size_t Exception) {
|
||||||
|
/* Only the first 32 ISR/IRQs are reserved for exceptions by the CPU. We can handle up to 512 interrupts total, though. */
|
||||||
|
if(Exception < 32) {
|
||||||
|
|
||||||
|
FillScreen(0x0000FF00);
|
||||||
|
/* ExceptionStrings is an array of c-strings defined in kernel.h */
|
||||||
|
|
||||||
|
//serialPrint(ExceptionStrings[Exception]);
|
||||||
|
//serialPrint(" Exception.\r\n");
|
||||||
|
//printf("%s exception!", ExceptionStrings[Exception]);
|
||||||
|
//panic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The common handler for exceptions that throw error codes, which give us useful insight
|
||||||
|
into what went wrong. In pure Curle style, though, we just ignore the error code. */
|
||||||
|
void ISR_Error_Common(INTERRUPT_FRAME* Frame, size_t ErrorCode, size_t Exception) {
|
||||||
|
if(Exception < 32) {
|
||||||
|
|
||||||
|
FillScreen(0x00FF0000);
|
||||||
|
|
||||||
|
SerialPrintf("ISR Error %d raised, EC %d!\r\n", Exception, ErrorCode);
|
||||||
|
|
||||||
|
while(true) {}
|
||||||
|
//serialPrint(ExceptionStrings[Exception]);
|
||||||
|
//serialPrintf(" Exception. Context given: %d\r\n", Frame->ErrorCode);
|
||||||
|
//printf("%s exception. Context: %x", ExceptionStrings[Exception], Frame->ErrorCode);
|
||||||
|
//panic();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Likewise, this function is common to all IRQ handlers. It calls the assigned routine,
|
||||||
|
which was set up earlier by irq_install.*/
|
||||||
|
void IRQ_Common(INTERRUPT_FRAME* Frame, size_t Interrupt) {
|
||||||
|
// First we need to define a function pointer..
|
||||||
|
void (*Handler)(INTERRUPT_FRAME* Frame);
|
||||||
|
|
||||||
|
// Tell the user we've got an interrupt in..
|
||||||
|
//serial_print(0x3F8, "[INFO] Received IRQ: " + interrupt);
|
||||||
|
//printf("[INFO] Received IRQ: %x", Interrupt);
|
||||||
|
|
||||||
|
/* We set all uninitialized routines to 0, so the if(handler) check here allows us to
|
||||||
|
safely tell whether we've actually got something for this IRQ. */
|
||||||
|
Handler = IRQ_Handlers[Interrupt];
|
||||||
|
// If there's something there,
|
||||||
|
if(Handler) {
|
||||||
|
SerialPrintf("IRQ %d raised!\r\n", Interrupt);
|
||||||
|
// Call the handler.
|
||||||
|
Handler(Frame);
|
||||||
|
}
|
||||||
|
/* The Slave PIC must be told it's been read in order to receive another 8+ IRQ. */
|
||||||
|
if(Interrupt > 7)
|
||||||
|
WritePort(0xA0, 0x20, 1);
|
||||||
|
|
||||||
|
/* In either case, we tell the Master PIC it's been read to receive any IRQ. */
|
||||||
|
WritePort(0x20, 0x20, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* However, in order to actually be able to receive IRQs, we need to remap the PICs. */
|
||||||
|
void RemapIRQControllers() {
|
||||||
|
/* 0x20 is the Master PIC,
|
||||||
|
0xA0 is the Slave PIC. */
|
||||||
|
WritePort(0x20, 0x11, 1);
|
||||||
|
WritePort(0xA0, 0x11, 1);
|
||||||
|
WritePort(0x21, 0x20, 1);
|
||||||
|
WritePort(0xA1, 0x28, 1);
|
||||||
|
WritePort(0x21, 0x04, 1);
|
||||||
|
WritePort(0xA1, 0x02, 1);
|
||||||
|
WritePort(0x21, 0x01, 1);
|
||||||
|
WritePort(0xA1, 0x01, 1);
|
||||||
|
WritePort(0x21, 0x0, 1);
|
||||||
|
WritePort(0xA1, 0x0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In order to actually handle the IRQs, though, we need to tell the kernel *where* the handlers are. */
|
||||||
|
/* A simple wrapper that adds a function pointer to the IRQ array. */
|
||||||
|
void InstallIRQ(int IRQ, void (*Handler)(INTERRUPT_FRAME* Frame)) {
|
||||||
|
IRQ_Handlers[IRQ] = Handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A simple wrapper that unlinks a function pointer, rendering the IRQ unused. */
|
||||||
|
void UninstallIRQHandler(int IRQ) {
|
||||||
|
IRQ_Handlers[IRQ] = 0; // 0 is used in the common check to make sure that the function is callable.
|
||||||
|
// This removes this irq from that check, ergo the function will no longer be called.
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmptyIRQ(INTERRUPT_FRAME* frame) {
|
||||||
|
// Flash the borders green, then back to blue
|
||||||
|
|
||||||
|
for(size_t y = 0; y < bootldr.fb_height; y++) {
|
||||||
|
for(size_t x = 0; x < 20; x++) {
|
||||||
|
DrawPixel(x, y, 0x0000FF00);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t x = (bootldr.fb_width - 20); x < bootldr.fb_width; x++) {
|
||||||
|
DrawPixel(x, y, 0x0000FF00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t x = 0; x < bootldr.fb_width; x++) {
|
||||||
|
for(size_t y = 0; y < 20; y++) {
|
||||||
|
DrawPixel(x, y, 0x0000FF00);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t y = (bootldr.fb_height - 20); y < bootldr.fb_height; y++) {
|
||||||
|
DrawPixel(x, y, 0x0000FF00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t y = 0; y < bootldr.fb_height; y++) {
|
||||||
|
for(size_t x = 0; x < 20; x++) {
|
||||||
|
DrawPixel(x, y, 0x000000FF);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t x = (bootldr.fb_width - 20); x < bootldr.fb_width; x++) {
|
||||||
|
DrawPixel(x, y, 0x000000FF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t x = 0; x < bootldr.fb_width; x++) {
|
||||||
|
for(size_t y = 0; y < 20; y++) {
|
||||||
|
DrawPixel(x, y, 0x000000FF);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t y = (bootldr.fb_height - 20); y < bootldr.fb_height; y++) {
|
||||||
|
DrawPixel(x, y, 0x000000FF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void KeyboardCallback(INTERRUPT_FRAME* frame) {
|
||||||
|
|
||||||
|
uint8_t msg = ReadPort(0x60, 1);
|
||||||
|
|
||||||
|
UpdateKeyboard(msg);
|
||||||
|
|
||||||
|
WaitFor8042();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitInterrupts() {
|
||||||
|
size_t RFLAGS = ReadControlRegister('f');
|
||||||
|
|
||||||
|
if(!(RFLAGS & (1 << 9))) {
|
||||||
|
WriteControlRegister('f', RFLAGS | (1 << 9));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
InstallIRQ(1, &KeyboardCallback);
|
||||||
|
|
||||||
|
Send8042(0xF002);
|
||||||
|
|
||||||
|
__asm__ __volatile__("sti");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The interrupt numbers, their meanings, and
|
||||||
|
* special information is laid out below:
|
||||||
|
*
|
||||||
|
* 0 - Divide by Zero
|
||||||
|
* 1 - Debug
|
||||||
|
* 2 - Non-Maskable
|
||||||
|
* 3 - Breakpoint
|
||||||
|
* 4 - Into Detected Overflow
|
||||||
|
* 5 - Out of Bounds
|
||||||
|
* 6 - Invalid Opcode
|
||||||
|
* 7 - No Coprocessor
|
||||||
|
* 8 - Double Fault * (With Error)
|
||||||
|
* 9 - Coprocessor Segment Overrun
|
||||||
|
* 10 - Bad TSS * (With Error)
|
||||||
|
* 11 - Segment Not Present * (With Error)
|
||||||
|
* 12 - Stack Fault * (With Error)
|
||||||
|
* 13 - General Protection Fault * (With Error)
|
||||||
|
* 14 - Page Fault * (With Error)
|
||||||
|
* 15 - Unknown Interrupt
|
||||||
|
* 16 - Coprocessor Fault
|
||||||
|
* 17 - Alignment Check
|
||||||
|
* 18 - Machine Check
|
||||||
|
* 19 to 31 - Reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
__attribute__((interrupt)) void ISR0Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
|
||||||
|
ISR_Common(Frame, 0);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR1Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 1);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR2Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 2);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR3Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 3);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR4Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 4);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR5Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 5);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR6Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 6);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR7Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 7);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR8Handler(INTERRUPT_FRAME* Frame, size_t ErrorCode) {
|
||||||
|
ISR_Error_Common(Frame, ErrorCode, 8);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR9Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 9);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR10Handler(INTERRUPT_FRAME* Frame, size_t ErrorCode) {
|
||||||
|
ISR_Error_Common(Frame, ErrorCode, 10);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR11Handler(INTERRUPT_FRAME* Frame, size_t ErrorCode) {
|
||||||
|
ISR_Error_Common(Frame, ErrorCode, 11);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR12Handler(INTERRUPT_FRAME* Frame, size_t ErrorCode) {
|
||||||
|
ISR_Error_Common(Frame, ErrorCode, 12);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR13Handler(INTERRUPT_FRAME* Frame, size_t ErrorCode) {
|
||||||
|
ISR_Error_Common(Frame, ErrorCode, 13); // General Protection
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR14Handler(INTERRUPT_FRAME* Frame, size_t ErrorCode) {
|
||||||
|
ISR_Error_Common(Frame, ErrorCode, 14);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR15Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 15);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR16Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 16);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR17Handler(INTERRUPT_FRAME* Frame, size_t ErrorCode) {
|
||||||
|
ISR_Error_Common(Frame, ErrorCode, 17);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR18Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 18);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR19Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 19);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR20Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 20);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR21Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 21);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR22Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 22);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR23Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 23);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR24Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 24);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR25Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 25);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR26Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 26);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR27Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 27);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR28Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 28);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR29Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 29);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR30Handler(INTERRUPT_FRAME* Frame, size_t ErrorCode) {
|
||||||
|
ISR_Error_Common(Frame, ErrorCode, 30);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void ISR31Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((interrupt)) void ReservedISRHandler(INTERRUPT_FRAME* Frame) {
|
||||||
|
ISR_Common(Frame, 33); // if < 32, isn't handled.
|
||||||
|
// Effectively disables this ISR.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__attribute__((interrupt)) void IRQ0Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
IRQ_Common(Frame, 0);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void IRQ1Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
IRQ_Common(Frame, 1); // Keyboard handler
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void IRQ2Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
IRQ_Common(Frame, 2);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void IRQ3Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
IRQ_Common(Frame, 3);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void IRQ4Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
IRQ_Common(Frame, 4);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void IRQ5Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
IRQ_Common(Frame, 5);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void IRQ6Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
IRQ_Common(Frame, 6);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void IRQ7Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
IRQ_Common(Frame, 7);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void IRQ8Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
IRQ_Common(Frame, 8);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void IRQ9Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
IRQ_Common(Frame, 9);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void IRQ10Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
IRQ_Common(Frame, 10);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void IRQ11Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
IRQ_Common(Frame, 11);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void IRQ12Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
IRQ_Common(Frame, 12);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void IRQ13Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
IRQ_Common(Frame, 13);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void IRQ14Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
IRQ_Common(Frame, 14);
|
||||||
|
}
|
||||||
|
__attribute__((interrupt)) void IRQ15Handler(INTERRUPT_FRAME* Frame) {
|
||||||
|
IRQ_Common(Frame, 15);
|
||||||
|
}
|
124
chroma/system/mem.c
Normal file
124
chroma/system/mem.c
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
#include <kernel/chroma.h>
|
||||||
|
|
||||||
|
uint8_t* Memory = ((uint8_t*)(&end));
|
||||||
|
uint8_t MemoryStart;
|
||||||
|
uint32_t MemoryPages;
|
||||||
|
uint32_t MemoryLength;
|
||||||
|
|
||||||
|
void InitMemoryManager() {
|
||||||
|
|
||||||
|
size_t BootstructSize = bootldr.size;
|
||||||
|
size_t BootstructLoc = (size_t) &bootldr;
|
||||||
|
|
||||||
|
size_t BootstructEnd = BootstructLoc + BootstructSize;
|
||||||
|
size_t MemorySize = 0, MemMapEntryCount = 0;
|
||||||
|
|
||||||
|
MMapEnt* MemMap = &bootldr.mmap;
|
||||||
|
|
||||||
|
while((size_t) MemMap < BootstructEnd) {
|
||||||
|
if(MMapEnt_IsFree(MemMap)) {
|
||||||
|
MemorySize += MMapEnt_Size(MemMap);
|
||||||
|
}
|
||||||
|
MemMapEntryCount++;
|
||||||
|
MemMap++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MemoryPages = MemorySize / PAGE_SIZE;
|
||||||
|
MemoryLength = MemoryPages / PAGES_PER_BUCKET;
|
||||||
|
|
||||||
|
if(MemoryLength * PAGES_PER_BUCKET < MemoryPages)
|
||||||
|
MemoryLength++; // Always round up
|
||||||
|
|
||||||
|
|
||||||
|
memset(Memory, 0, MemoryLength);
|
||||||
|
|
||||||
|
MemoryStart = (uint8_t*)PAGE_ALIGN(((uint32_t)(Memory + MemoryLength)));
|
||||||
|
|
||||||
|
|
||||||
|
SerialPrintf("Initializing Memory.\r\n");
|
||||||
|
|
||||||
|
SerialPrintf("%u MB of memory detected.\r\n", (MemorySize / 1024) / 1024);
|
||||||
|
|
||||||
|
for(size_t i = 0; i < MemoryLength; i++) {
|
||||||
|
if(Memory[i] != 0)
|
||||||
|
SerialPrintf("Memory at 0x%p is not empty!", Memory + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AllocatePage() {
|
||||||
|
size_t FreePage = FirstFreePage();
|
||||||
|
SET_BIT(FreePage);
|
||||||
|
return FreePage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreePage(size_t Page) {
|
||||||
|
UNSET_BIT(Page);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FirstFreePage() {
|
||||||
|
for(size_t i = 0; i < MemoryPages; i++) {
|
||||||
|
if(!READ_BIT(i))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
SerialPrintf("Memory manager: Critical!\r\n");
|
||||||
|
return (size_t) -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryTest() {
|
||||||
|
SerialPrintf("Initializing basic memory test..\r\n");
|
||||||
|
bool Passed = true;
|
||||||
|
size_t FirstPage = FirstFreePage();
|
||||||
|
void* FirstPageAlloc = AllocatePage();
|
||||||
|
size_t SecondPage = FirstFreePage();
|
||||||
|
void* SecondPageAlloc = AllocatePage();
|
||||||
|
|
||||||
|
if(!(FirstPage == 0 && SecondPage == 1)) {
|
||||||
|
Passed = false;
|
||||||
|
SerialPrintf("First iteration: Failed, First page %x, Second page %x.\r\n", FirstPage, SecondPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
FreePage(SecondPage);
|
||||||
|
SecondPage = FirstFreePage();
|
||||||
|
|
||||||
|
if(SecondPage != 1)
|
||||||
|
Passed = false;
|
||||||
|
|
||||||
|
FreePage(FirstPage);
|
||||||
|
FirstPage = FirstFreePage();
|
||||||
|
|
||||||
|
if(FirstPage != 0)
|
||||||
|
Passed = false;
|
||||||
|
|
||||||
|
if(Passed)
|
||||||
|
SerialPrintf("Memory test passed.\r\n");
|
||||||
|
else {
|
||||||
|
SerialPrintf("Memory test failed.\r\n");
|
||||||
|
SerialPrintf("First page %x, Second page %x.\r\n", FirstPage, SecondPage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* memcpy(void* dest, void const* src, size_t len) {
|
||||||
|
unsigned char* dst = (unsigned char*) dest;
|
||||||
|
const unsigned char* source = (const unsigned char*) src;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < len; i++) {
|
||||||
|
dst[i] = source[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* memset(void* dst, int src, size_t len) {
|
||||||
|
unsigned char* buf = (unsigned char*) dst;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < len; i++) {
|
||||||
|
buf[i] = (unsigned char) src;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
216
chroma/system/rw.c
Normal file
216
chroma/system/rw.c
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
#include <kernel/chroma.h>
|
||||||
|
|
||||||
|
uint32_t ReadPort(uint16_t Port, int Length) {
|
||||||
|
uint32_t Data = 0;
|
||||||
|
uint16_t Data16 = 0;
|
||||||
|
uint8_t Data8 = 0;
|
||||||
|
|
||||||
|
if(Length == 1) {
|
||||||
|
__asm__ __volatile__ ("inb %[address], %[value]" : [value] "=a" (Data8) : [address] "d" (Port) :);
|
||||||
|
Data = (uint32_t) Data8;
|
||||||
|
} else if(Length == 2) {
|
||||||
|
__asm__ __volatile__ ("inw %[address], %[value]" : [value] "=a" (Data16) : [address] "d" (Port) :);
|
||||||
|
Data = (uint32_t) Data16;
|
||||||
|
} else if(Length == 4)
|
||||||
|
__asm__ __volatile__ ("inl %[address], %[value]" : [value] "=a" (Data) : [address] "d" (Port) :);
|
||||||
|
//else
|
||||||
|
//printf("Readport: Invalid length\r\n");
|
||||||
|
|
||||||
|
return Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t WritePort(uint16_t Port, uint32_t Data, int Length) {
|
||||||
|
if(Length == 1)
|
||||||
|
__asm__ __volatile__ ("outb %[value], %[address]" : : [value] "a" ((uint8_t) Data), [address] "d" (Port) :);
|
||||||
|
else if(Length == 2)
|
||||||
|
__asm__ __volatile__ ("outw %[value], %[address]" : : [value] "a" ((uint16_t) Data), [address] "d" (Port) :);
|
||||||
|
else if(Length == 4)
|
||||||
|
__asm__ __volatile__ ("outl %[value], %[address]" : : [value] "a" (Data), [address] "d" (Port) :);
|
||||||
|
//else
|
||||||
|
//printf("WritePort: Invalid length.\r\n");
|
||||||
|
|
||||||
|
return Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ReadModelSpecificRegister(size_t MSR) {
|
||||||
|
size_t RegHigh = 0, RegLow = 0;
|
||||||
|
|
||||||
|
__asm__ __volatile__ ("rdmsr" : "=a" (RegLow), "=d" (RegHigh) : "c" (MSR) :);
|
||||||
|
|
||||||
|
return RegHigh << 32 | RegLow;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t WriteModelSpecificRegister(size_t MSR, size_t Data) {
|
||||||
|
size_t DataLow = 0, DataHigh = 0;
|
||||||
|
|
||||||
|
DataLow = ((uint32_t*) &Data)[0];
|
||||||
|
DataHigh = ((uint32_t*) &Data)[1];
|
||||||
|
|
||||||
|
__asm__ __volatile__ ("wrmsr" : : "a" (DataLow), "c" (MSR), "d" (DataHigh) :);
|
||||||
|
|
||||||
|
return Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ReadVexMXCSR() {
|
||||||
|
uint32_t Data;
|
||||||
|
|
||||||
|
__asm__ __volatile__ ("vstmxcsr %[dest]" : [dest] "=m" (Data) : :);
|
||||||
|
return Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t WriteVexMXCSR(uint32_t Data) {
|
||||||
|
|
||||||
|
__asm__ __volatile__ ("vldmxcsr %[src]" : : [src] "m" (Data) :);
|
||||||
|
return Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ReadMXCSR() {
|
||||||
|
uint32_t Data;
|
||||||
|
|
||||||
|
__asm__ __volatile__ ("stmxcsr %[dest]" : [dest] "=m" (Data) : :);
|
||||||
|
return Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t WriteMXCSR(uint32_t Data) {
|
||||||
|
|
||||||
|
__asm__ __volatile__ ("ldmxcsr %[src]" : : [src] "m" (Data) :);
|
||||||
|
return Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ReadControlRegister(int CRX) {
|
||||||
|
|
||||||
|
size_t Data;
|
||||||
|
|
||||||
|
switch(CRX) {
|
||||||
|
case 0:
|
||||||
|
__asm__ __volatile__ ("mov %%cr0, %[dest]" : [dest] "=r" (Data) : :);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
__asm__ __volatile__ ("mov %%cr1, %[dest]" : [dest] "=r" (Data) : :);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
__asm__ __volatile__ ("mov %%cr2, %[dest]" : [dest] "=r" (Data) : :);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
__asm__ __volatile__ ("mov %%cr3, %[dest]" : [dest] "=r" (Data) : :);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
__asm__ __volatile__ ("mov %%cr4, %[dest]" : [dest] "=r" (Data) : :);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
__asm__ __volatile__ ("mov %%cr8, %[dest]" : [dest] "=r" (Data) : :);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
__asm__ __volatile__ ("pushfq\n\t" "popq %[dest]" : [dest] "=r" (Data) : :);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t WriteControlRegister(int CRX, size_t Data) {
|
||||||
|
switch(CRX) {
|
||||||
|
case 0:
|
||||||
|
__asm__ __volatile__ ("mov %[dest], %%cr0" : : [dest] "r" (Data) : );
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
__asm__ __volatile__ ("mov %[dest], %%cr1" : : [dest] "r" (Data) : );
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
__asm__ __volatile__ ("mov %[dest], %%cr2" : : [dest] "r" (Data) : );
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
__asm__ __volatile__ ("mov %[dest], %%cr3" : : [dest] "r" (Data) : );
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
__asm__ __volatile__ ("mov %[dest], %%cr4" : : [dest] "r" (Data) : );
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
__asm__ __volatile__ ("mov %[dest], %%cr8" : : [dest] "r" (Data) : );
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
__asm__ __volatile__ ("pushq %[dest]\n\t" "popfq" : : [dest] "r" (Data) : "cc");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ReadExtendedControlRegister(size_t XCRX) {
|
||||||
|
size_t RegHigh = 0, RegLow = 0;
|
||||||
|
|
||||||
|
__asm__ __volatile__("xgetbv" : "=a" (RegLow), "=d" (RegHigh) : "c" (XCRX) :);
|
||||||
|
|
||||||
|
return (RegHigh << 32 | RegLow);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t WriteExtendedControlRegister(size_t XCRX, size_t Data){
|
||||||
|
|
||||||
|
__asm__ __volatile__("xsetbv" : : "a" ( ((uint32_t*) &Data)[0]), "c" (XCRX), "d" ( ((uint32_t*) &Data)[1] ) :);
|
||||||
|
return Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ReadXCS() {
|
||||||
|
size_t Data;
|
||||||
|
|
||||||
|
__asm__ __volatile__("mov %%cs, %[dest]" : [dest] "=r" (Data) : :);
|
||||||
|
return Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
DESC_TBL ReadGDT() {
|
||||||
|
DESC_TBL GDTData = {0};
|
||||||
|
|
||||||
|
__asm__ __volatile__("sgdt %[dest]" : [dest] "=m" (GDTData) : :);
|
||||||
|
|
||||||
|
return GDTData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteGDT(DESC_TBL GDTData) {
|
||||||
|
|
||||||
|
__asm__ __volatile__("lgdt %[src]" : : [src] "m" (GDTData) :);
|
||||||
|
}
|
||||||
|
|
||||||
|
DESC_TBL ReadIDT() {
|
||||||
|
DESC_TBL IDTData = {0};
|
||||||
|
|
||||||
|
__asm__ __volatile__("sidt %[dest]" : [dest] "=m" (IDTData) : :);
|
||||||
|
|
||||||
|
return IDTData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteIDT(DESC_TBL IDTData) {
|
||||||
|
|
||||||
|
__asm__ __volatile__("lidt %[src]" : : [src] "m" (IDTData) :);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ReadLDT() {
|
||||||
|
uint16_t LDTData;
|
||||||
|
|
||||||
|
__asm__ __volatile__("sldt %[dest]" : [dest] "=m" (LDTData) : :);
|
||||||
|
|
||||||
|
return LDTData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteLDT(uint16_t LDTData) {
|
||||||
|
|
||||||
|
__asm__ __volatile__("lldt %[src]" : : [src] "m" (LDTData) :);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ReadTSR() {
|
||||||
|
uint16_t TSRData;
|
||||||
|
|
||||||
|
__asm__ __volatile__("str %[dest]" : [dest] "=m" (TSRData) : :);
|
||||||
|
|
||||||
|
return TSRData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteTSR(uint16_t TSRData) {
|
||||||
|
|
||||||
|
__asm__ __volatile__("ltr %[src]" : : [src] "m" (TSRData) :);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
40
chroma/system/serial.c
Normal file
40
chroma/system/serial.c
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#include <kernel/chroma.h>
|
||||||
|
|
||||||
|
#define SERIAL_DATA(base) (base)
|
||||||
|
#define SERIAL_DLAB(base) (base + 1)
|
||||||
|
#define SERIAL_FIFO(base) (base + 2)
|
||||||
|
#define SERIAL_LINE(base) (base + 3)
|
||||||
|
#define SERIAL_MODEM(base) (base + 4)
|
||||||
|
#define SERIAL_LINE_STATUS(base) (base + 5)
|
||||||
|
#define COM1 0x3F8
|
||||||
|
|
||||||
|
void InitSerial() {
|
||||||
|
// Disable interrupts
|
||||||
|
WritePort(SERIAL_DLAB(COM1), 0x00, 1);
|
||||||
|
// Set baud rate to /3 (115200 bits/sec)
|
||||||
|
WritePort(SERIAL_LINE(COM1), 0x80, 1);
|
||||||
|
WritePort(SERIAL_DATA(COM1), 0x03, 1);
|
||||||
|
WritePort(SERIAL_DLAB(COM1), 0x00, 1);
|
||||||
|
// Set serial to 8 bits, no parity and one stop bit.
|
||||||
|
WritePort(SERIAL_LINE(COM1), 0x03, 1);
|
||||||
|
// Enable FIFO and clear all buffers
|
||||||
|
WritePort(SERIAL_FIFO(COM1), 0xC7, 1);
|
||||||
|
// Enable IRQs, set RTS and DSR
|
||||||
|
WritePort(SERIAL_MODEM(COM1), 0x03, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int CheckSerial() {
|
||||||
|
return ReadPort(SERIAL_LINE_STATUS(COM1), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteSerialChar(const char chr) {
|
||||||
|
while(!(CheckSerial() & 0x20));
|
||||||
|
WritePort(COM1, chr, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteSerialString(const char* str, size_t len) {
|
||||||
|
for(size_t i = 0; i < len; i++) {
|
||||||
|
WriteSerialChar(str[i]);
|
||||||
|
}
|
||||||
|
}
|
264
chroma/video/draw.c
Normal file
264
chroma/video/draw.c
Normal file
|
@ -0,0 +1,264 @@
|
||||||
|
#include <kernel/chroma.h>
|
||||||
|
#include <kernel/video/bitmapfont.h>
|
||||||
|
|
||||||
|
#define FONT bitfont_latin
|
||||||
|
|
||||||
|
static size_t strlen(const char* String) {
|
||||||
|
size_t Len = 0;
|
||||||
|
while(String[Len] != '\0') {
|
||||||
|
Len++;
|
||||||
|
}
|
||||||
|
return Len;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t charHeight;
|
||||||
|
uint32_t charWidth;
|
||||||
|
uint32_t charFGColor;
|
||||||
|
uint32_t charHLColor;
|
||||||
|
uint32_t charBGColor;
|
||||||
|
uint32_t minX;
|
||||||
|
uint32_t minY;
|
||||||
|
uint32_t charScale;
|
||||||
|
size_t charPosX;
|
||||||
|
size_t charPosY;
|
||||||
|
size_t charsPerRow;
|
||||||
|
size_t rowsPerScrn;
|
||||||
|
uint32_t scrlMode;
|
||||||
|
} PRINTINFO;
|
||||||
|
|
||||||
|
PRINTINFO PrintInfo = {0};
|
||||||
|
|
||||||
|
void InitPrint() {
|
||||||
|
PrintInfo.charHeight = 8;
|
||||||
|
PrintInfo.charWidth = 8;
|
||||||
|
PrintInfo.charFGColor = 0x00FFFFFF;
|
||||||
|
PrintInfo.charHLColor = 0x00000000;
|
||||||
|
PrintInfo.charBGColor = 0x00000000;
|
||||||
|
|
||||||
|
PrintInfo.charScale = 2;
|
||||||
|
|
||||||
|
PrintInfo.charPosX = 0;
|
||||||
|
PrintInfo.charPosY = 0;
|
||||||
|
|
||||||
|
PrintInfo.scrlMode = 0;
|
||||||
|
|
||||||
|
PrintInfo.charsPerRow = bootldr.fb_width / (PrintInfo.charScale * PrintInfo.charWidth) - 5;
|
||||||
|
PrintInfo.rowsPerScrn = bootldr.fb_height / (PrintInfo.charScale * PrintInfo.charHeight);
|
||||||
|
SerialPrintf("A single character is %ux%u pixels.\r\n", PrintInfo.charScale * PrintInfo.charWidth, PrintInfo.charScale * PrintInfo.charHeight);
|
||||||
|
SerialPrintf("The screen is %ux%u, meaning you can fit %ux%u characters on screen.\r\n", bootldr.fb_width, bootldr.fb_height, PrintInfo.charsPerRow, PrintInfo.rowsPerScrn);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawChar(const char character, size_t x, size_t y) {
|
||||||
|
x = x + PrintInfo.charPosX * (PrintInfo.charScale * PrintInfo.charWidth);
|
||||||
|
y = y + PrintInfo.charPosY * (PrintInfo.charScale * PrintInfo.charHeight);
|
||||||
|
|
||||||
|
uint32_t Y = PrintInfo.charWidth >> 3, X = 0;
|
||||||
|
|
||||||
|
if((PrintInfo.charWidth & 0x7) != 0) {
|
||||||
|
Y++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(uint32_t Row = 0; Row < PrintInfo.charHeight; Row++) {
|
||||||
|
|
||||||
|
|
||||||
|
for(uint32_t Bit = 0; Bit < PrintInfo.charWidth; Bit++) {
|
||||||
|
if ( ((Bit & 0x7) == 0) && (Bit > 0)) {
|
||||||
|
X++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((FONT[character][Row * Y + X] >> (Bit & 0x7)) & 1) {
|
||||||
|
for(uint32_t ScaleY = 0; ScaleY < PrintInfo.charScale; ScaleY++) {
|
||||||
|
for(uint32_t ScaleX = 0; ScaleX < PrintInfo.charScale; ScaleX++) {
|
||||||
|
|
||||||
|
size_t offset = ((y * bootldr.fb_width + x) +
|
||||||
|
PrintInfo.charScale * (Row * bootldr.fb_width + Bit) +
|
||||||
|
(ScaleY * bootldr.fb_width + ScaleX) +
|
||||||
|
PrintInfo.charScale * 1 * PrintInfo.charWidth) - 10;
|
||||||
|
|
||||||
|
// This one is crazy. Stick with me.
|
||||||
|
*(uint32_t* )(&fb + offset * 4)// Offset from the framebuffer, find the pixel..
|
||||||
|
// and find which column we need to be in. Multiply by 4 to navigate the 4bpp array,
|
||||||
|
= PrintInfo.charFGColor; // And set the color of the pixel.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We need to draw the pixel transparently..
|
||||||
|
for(uint32_t ScaleY = 0; ScaleY < PrintInfo.charScale; ScaleY++) {
|
||||||
|
for(uint32_t ScaleX = 0; ScaleX < PrintInfo.charScale; ScaleX++) {
|
||||||
|
if(PrintInfo.charHLColor != 0xFF000000) {
|
||||||
|
size_t offset = ((y * bootldr.fb_width + x) +
|
||||||
|
PrintInfo.charScale * (Row * bootldr.fb_width + Bit) +
|
||||||
|
(ScaleY * bootldr.fb_width + ScaleX) +
|
||||||
|
PrintInfo.charScale * 1 * PrintInfo.charWidth) - 10;
|
||||||
|
if( y == 0 && x == 0){
|
||||||
|
SerialPrintf("Writing first pixel at %x\r\n", offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
*(uint32_t*)(&fb + offset *4)
|
||||||
|
= PrintInfo.charHLColor;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
uint32_t Y = PrintInfo.charWidth >> 3, X = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if((PrintInfo.charWidth & 0x7) != 0) {
|
||||||
|
Y++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t CharRow = 0; CharRow < PrintInfo.charHeight; CharRow++) {
|
||||||
|
for(size_t CharPixel = 0; CharPixel < PrintInfo.charWidth; CharPixel++) {
|
||||||
|
if( CharPixel && (CharPixel & 0x7) == 0) {
|
||||||
|
X++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t ScaleX = 0; ScaleX < PrintInfo.charScale; ScaleX++) {
|
||||||
|
for(size_t ScaleY = 0; ScaleY < PrintInfo.charScale; ScaleY++) {
|
||||||
|
|
||||||
|
if(FONT[character][CharRow * Y + X] >> (CharRow & 0x7) & 1) {
|
||||||
|
|
||||||
|
size_t offset = (y * bootldr.fb_width + x) +
|
||||||
|
(PrintInfo.charScale * (CharRow * bootldr.fb_width + CharPixel)) +
|
||||||
|
(ScaleY * (bootldr.fb_width + ScaleX));
|
||||||
|
|
||||||
|
|
||||||
|
*((uint32_t*) (&fb + offset * 4))
|
||||||
|
= PrintInfo.charFGColor;
|
||||||
|
//DrawPixel(x * PrintInfo.charWidth + X, Y + y + PrintInfo.charHeight, 0x00FF0000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Y = PrintInfo.charWidth >> 3, X = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if((PrintInfo.charWidth & 0x7) != 0) {
|
||||||
|
Y++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(uint32_t Row = 0; Row < PrintInfo.charHeight; Row++) {
|
||||||
|
for(uint32_t Bit = 0; Bit < PrintInfo.charWidth; Bit++) {
|
||||||
|
if( ((Bit & 0x7) == 0) && (Bit > 0))
|
||||||
|
X++;
|
||||||
|
|
||||||
|
for(uint32_t ScaleY = 0; ScaleY < PrintInfo.charScale; ScaleY++) {
|
||||||
|
for(uint32_t ScaleX = 0; ScaleX < PrintInfo.charScale; ScaleX++) {
|
||||||
|
if((FONT[character][Row * Y + X] >> (Bit & 0x7)) & 1) {
|
||||||
|
size_t offset = (y * bootldr.fb_width + x) +
|
||||||
|
(PrintInfo.charScale * (Row * bootldr.fb_width + Bit)) +
|
||||||
|
(ScaleY * (bootldr.fb_width + ScaleX));
|
||||||
|
SerialPrintf("Drawing pixel at offset %x, at y %d, x %d, row %d, bit %d with scaley %d and scalex %d. charScale %d and charWidth %d, making a charLength %d.\r\n", offset, y, x, Row, Bit, ScaleX, ScaleY, PrintInfo.charScale, PrintInfo.charWidth, PrintInfo.charScale * PrintInfo.charWidth);
|
||||||
|
|
||||||
|
*((uint32_t*) (&fb + offset * 4))
|
||||||
|
= PrintInfo.charFGColor;
|
||||||
|
} else {
|
||||||
|
if(PrintInfo.charHLColor != 0xFF000000) {
|
||||||
|
size_t offset = (y * bootldr.fb_width + x) +
|
||||||
|
(PrintInfo.charScale * (Row * bootldr.fb_width + Bit)) +
|
||||||
|
(ScaleY * (bootldr.fb_width + ScaleX));
|
||||||
|
SerialPrintf("Drawing pixel at offset %x\r\n", offset);
|
||||||
|
|
||||||
|
*((uint32_t*) (&fb + offset * 4))
|
||||||
|
= PrintInfo.charHLColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawPixel(uint32_t x, uint32_t y, uint32_t color) {
|
||||||
|
if(x > bootldr.fb_width) {
|
||||||
|
DrawPixel(x - bootldr.fb_width, y + (PrintInfo.charHeight * PrintInfo.charScale), color);
|
||||||
|
//FillScreen(color);
|
||||||
|
} else if(y > bootldr.fb_height) {
|
||||||
|
DrawPixel(x, y - bootldr.fb_height, color);
|
||||||
|
} else {
|
||||||
|
*((uint32_t*) (&fb + (y * bootldr.fb_scanline + x) * 4)) = color;
|
||||||
|
SerialPrintf("Drawing a pixel at %d, %d with color 0x%x\r\n", x, y, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FillScreen(uint32_t color) {
|
||||||
|
for(size_t y = 0; y < bootldr.fb_height; y++) {
|
||||||
|
for(size_t x = 0; x < bootldr.fb_width; x++) {
|
||||||
|
DrawPixel(x, y, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ProgressCursorS(size_t Steps) {
|
||||||
|
if(PrintInfo.charPosX + Steps > PrintInfo.charsPerRow) {
|
||||||
|
PrintInfo.charPosX = 0;
|
||||||
|
size_t Rows = Steps / PrintInfo.charsPerRow;
|
||||||
|
if(PrintInfo.charPosY + Rows > PrintInfo.rowsPerScrn) {
|
||||||
|
size_t RowsLeft = PrintInfo.rowsPerScrn - PrintInfo.charPosY;
|
||||||
|
ProgressCursorS((Rows - RowsLeft) * PrintInfo.charsPerRow);
|
||||||
|
} else {
|
||||||
|
PrintInfo.charPosY++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PrintInfo.charPosX += Steps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Newline() {
|
||||||
|
ProgressCursorS(PrintInfo.charsPerRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ProgressCursor() {
|
||||||
|
ProgressCursorS(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteChar(const char character) {
|
||||||
|
|
||||||
|
//size_t y = PrintInfo.charPos / RowsWidth * (PrintInfo.charScale * PrintInfo.charHeight);
|
||||||
|
//size_t x = (PrintInfo.charPos % RowsWidth) * (PrintInfo.charScale * PrintInfo.charWidth);
|
||||||
|
|
||||||
|
switch(character) {
|
||||||
|
case '\b':
|
||||||
|
if(PrintInfo.charPosX - 1 == 0) {
|
||||||
|
if(PrintInfo.charPosY - 1 == 0) {
|
||||||
|
PrintInfo.charPosY = 0;
|
||||||
|
} else {
|
||||||
|
PrintInfo.charPosY--;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PrintInfo.charPosX = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
Newline();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DrawChar(character, PrintInfo.charPosX, PrintInfo.charPosY);
|
||||||
|
|
||||||
|
ProgressCursor();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void WriteString(const char* string) {
|
||||||
|
for(int i = 0; i < strlen(string); i++) {
|
||||||
|
WriteChar(string[i]);
|
||||||
|
}
|
||||||
|
}
|
109
chroma/video/print.c
Normal file
109
chroma/video/print.c
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
#include <kernel/chroma.h>
|
||||||
|
|
||||||
|
static size_t strlen(const char* String) {
|
||||||
|
size_t Len = 0;
|
||||||
|
while(String[Len] != '\0') {
|
||||||
|
Len++;
|
||||||
|
}
|
||||||
|
return Len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void NumToStr(char* Buffer, size_t Num, size_t Base) {
|
||||||
|
size_t Temp, i = 0, j = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
Temp = Num % Base;
|
||||||
|
Buffer[i++] = (Temp < 10) ? (Temp + '0') : (Temp + 'a' - 10);
|
||||||
|
} while (Num /= Base);
|
||||||
|
|
||||||
|
Buffer[i--] = 0;
|
||||||
|
|
||||||
|
for(j = 0; j < i; j++, i--) {
|
||||||
|
Temp = Buffer[j];
|
||||||
|
Buffer[j] = Buffer[i];
|
||||||
|
Buffer[i] = Temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int SerialPrintf(const char* restrict Format, ...) {
|
||||||
|
va_list Parameters;
|
||||||
|
va_start(Parameters, Format);
|
||||||
|
|
||||||
|
int CharsWritten = 0;
|
||||||
|
size_t Base, Num;
|
||||||
|
|
||||||
|
char BufferStr[512] = {0};
|
||||||
|
|
||||||
|
while(*Format != '\0') {
|
||||||
|
size_t Limit = UINT64_MAX - CharsWritten;
|
||||||
|
|
||||||
|
if(*Format == '%') {
|
||||||
|
if(*(++Format) == '%')
|
||||||
|
Format++;
|
||||||
|
|
||||||
|
|
||||||
|
switch(*Format) {
|
||||||
|
case 'c':
|
||||||
|
Format++;
|
||||||
|
|
||||||
|
char c = (char) va_arg(Parameters, int);
|
||||||
|
|
||||||
|
WriteSerialString(&c, sizeof(c));
|
||||||
|
|
||||||
|
CharsWritten++;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
Format++;
|
||||||
|
const char* Str = va_arg(Parameters, char*);
|
||||||
|
|
||||||
|
size_t Len = strlen(Str);
|
||||||
|
|
||||||
|
if(Limit < Len)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
WriteSerialString(Str, Len);
|
||||||
|
|
||||||
|
CharsWritten += Len;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
case 'u':
|
||||||
|
case 'p':
|
||||||
|
case 'x':
|
||||||
|
|
||||||
|
Num = va_arg(Parameters, size_t);
|
||||||
|
Base = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if(*Format == 'd' || *Format == 'u') {
|
||||||
|
Base = 10; // Decimal & Unsigned are base 10
|
||||||
|
} else {
|
||||||
|
Base = 16; // Hex and Ptr are base 16
|
||||||
|
}
|
||||||
|
Format++;
|
||||||
|
|
||||||
|
NumToStr(BufferStr, Num, Base);
|
||||||
|
Len = strlen(BufferStr);
|
||||||
|
|
||||||
|
WriteSerialString(BufferStr, Len);
|
||||||
|
|
||||||
|
CharsWritten += Len;
|
||||||
|
break;
|
||||||
|
//case 'p':
|
||||||
|
//uint8_t Base = 16;
|
||||||
|
//size_t Dest = (uintptr_t) va_arg(Parameters, void*);
|
||||||
|
default:
|
||||||
|
WriteSerialString("%u", 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
WriteSerialChar(*Format);
|
||||||
|
Format++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(Parameters);
|
||||||
|
return CharsWritten;
|
||||||
|
}
|
||||||
|
|
61
chroma/video/tty.c
Normal file
61
chroma/video/tty.c
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <kernel/video/tty.h>
|
||||||
|
|
||||||
|
#include <kernel/video/vga-textmode.h>
|
||||||
|
|
||||||
|
static const size_t TERM_WIDTH = 80;
|
||||||
|
static const size_t TERM_HEIGHT = 25;
|
||||||
|
|
||||||
|
size_t TERM_ROW;
|
||||||
|
size_t TERM_COL;
|
||||||
|
uint8_t TERM_COLOR;
|
||||||
|
|
||||||
|
uint16_t* TERM_BUFFER;
|
||||||
|
|
||||||
|
void Term_Init(void) {
|
||||||
|
|
||||||
|
TERM_ROW = 0;
|
||||||
|
TERM_COL = 0;
|
||||||
|
TERM_COLOR = VGACharColor(VGA_COLOR_LIGHTGREY, VGA_COLOR_BLACK);
|
||||||
|
|
||||||
|
TERM_BUFFER = (uint16_t*) 0xB8000;
|
||||||
|
|
||||||
|
for(size_t y = 0; y < TERM_HEIGHT; y++) {
|
||||||
|
for(size_t x = 0; x < TERM_WIDTH; x++) {
|
||||||
|
const size_t index = y * TERM_WIDTH + x;
|
||||||
|
TERM_BUFFER[index] = VGAChar(' ', TERM_COLOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Term_SetColor(uint8_t color) {
|
||||||
|
TERM_COLOR = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Term_PutVGAChar(char c, uint8_t color, size_t x, size_t y) {
|
||||||
|
const size_t index = y * TERM_WIDTH + x;
|
||||||
|
TERM_BUFFER[index] = VGAChar(c, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Term_PutChar(char c) {
|
||||||
|
Term_PutVGAChar(c, TERM_COLOR, TERM_COL, TERM_ROW);
|
||||||
|
|
||||||
|
if(++TERM_COL == TERM_WIDTH) {
|
||||||
|
TERM_COL = 0;
|
||||||
|
if(++TERM_ROW == TERM_HEIGHT)
|
||||||
|
TERM_ROW = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Term_Write(const char* str, size_t len) {
|
||||||
|
for(size_t i = 0; i < len; i++)
|
||||||
|
Term_PutChar(str[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Term_WriteString(const char* str) {
|
||||||
|
Term_Write(str, strlen(str));
|
||||||
|
}
|
||||||
|
|
BIN
iso/boot/bootloader
Normal file
BIN
iso/boot/bootloader
Normal file
Binary file not shown.
4
iso/boot/grub/grub.cfg
Normal file
4
iso/boot/grub/grub.cfg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
menuentry "Sync" {
|
||||||
|
multiboot /boot/bootloader
|
||||||
|
module /boot/initrd
|
||||||
|
}
|
31
linker.ld
Normal file
31
linker.ld
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
|
||||||
|
mmio = 0xfffffffff8000000;
|
||||||
|
fb = 0xfffffffffc000000;
|
||||||
|
|
||||||
|
PHDRS
|
||||||
|
{
|
||||||
|
boot PT_LOAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0xffffffffffe00000;
|
||||||
|
bootldr = .; . += 4096;
|
||||||
|
environment = .; . += 4096;
|
||||||
|
|
||||||
|
|
||||||
|
.text : {
|
||||||
|
KEEP(*(.text.boot)) *(.text .text.*)
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
*(.data .data.*)
|
||||||
|
} :boot
|
||||||
|
.bss (NOLOAD) : {
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
} :boot
|
||||||
|
|
||||||
|
/DISCARD/ : { *(.eh_frame) *(.comment) }
|
||||||
|
|
||||||
|
end = .;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user