I'm working on a simple operating system, and I've come across an error I just can't figure out how to get rid of:
kernel.c:100:22: error: initializer element is not constant
100 | static u32 *BUFFER = (u32 *) (modeInfo->PhysBasePtr);
| ^
I tried a few little things to fix this, though I'm not sure how to go about making this work. For a bit of context, I'm trying to get VESA graphics up and running for my OS, and the problematic line is one that establishes a buffer for double buffering (I was struggling with a flickering issue). Here I'll leave kernel.c
and a link to my GitHub:
kernel.c:
/*
TODO:
-Filesystem
-Mouse Inputs
-Simple GUI
-3d Viewer
-Maybe Link Downloader and Viewer
*/
#define NULL ((void*)0)
#define true 1
#define false 0
typedef unsigned char uint8_t;
typedef unsigned char u8;
typedef unsigned short uint16_t;
typedef unsigned int u32;
typedef u32 size_t;
typedef unsigned long phys_bytes;
#define SCREEN_WIDTH (int)(modeInfo->XResolution)
#define SCREEN_HEIGHT (int)(modeInfo->YResolution)
#define BPP 32
#define SCREEN_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT)
#define FPS 30
#define PIT_HERTZ 1193131.666
#define CLOCK_HIT (int)(PIT_HERTZ/FPS)
#define KEY_LEFT 0x4B
#define KEY_UP 0x48
#define KEY_RIGHT 0x4D
#define KEY_DOWN 0x50
void * malloc(size_t len) {
static size_t curoff = 0;
static char space[1 * 1024 * 1024 * 1024];
void *ptr = NULL;
if ((curoff len) < sizeof(space)) {
ptr = &space[curoff]; curoff = len;
} return ptr;
}
typedef struct VBE_modeInfo{
/* Mandatory information for all VBE revisions */
uint16_t ModeAttributes;
uint8_t WinAAttributes;
uint8_t WinBAttributes;
uint16_t WinGranularity;
uint16_t WinSize;
uint16_t WinASegment;
uint16_t WinBSegment;
phys_bytes WinFuncPtr;
uint16_t BytesPerScanLine;
/* Mandatory information for VBE 1.2 and above */
uint16_t XResolution;
uint16_t YResolution;
uint8_t XCharSize;
uint8_t YCharSize;
uint8_t NumberOfPlanes;
uint8_t BitsPerPixel;
uint8_t NumberOfBanks;
uint8_t MemoryModel;
uint8_t BankSize;
uint8_t NumberOfImagePages;
uint8_t Reserved1;
/* Direct Color fields (required for direct/6 and YUV/7 memory models) */
uint8_t RedMaskSize; /* size of direct color red mask in bits */
uint8_t RedFieldPosition; /* bit position of lsb of red mask */
uint8_t GreenMaskSize; /* size of direct color green mask in bits */
uint8_t GreenFieldPosition; /* bit position of lsb of green mask */
uint8_t BlueMaskSize; /* size of direct color blue mask in bits */
uint8_t BlueFieldPosition; /* bit position of lsb of blue mask */
uint8_t RsvdMaskSize; /* size of direct color reserved mask in bits */
uint8_t RsvdFieldPosition; /* bit position of lsb of reserved mask */
uint8_t DirectColorModeInfo; /* direct color mode attributes */
/* Mandatory information for VBE 2.0 and above */
phys_bytes PhysBasePtr;
uint8_t Reserved2[4];
uint8_t Reserved3[2];
/* Mandatory information for VBE 3.0 and above */
uint16_t LinBytesPerScanLine; /* bytes per scan line for linear modes */
uint8_t BnkNumberOfImagePages; /* number of images for banked modes */
uint8_t LinNumberOfImagePages; /* number of images for linear modes */
uint8_t LinRedMaskSize; /* size of direct color red mask (linear modes) */
uint8_t LinRedFieldPosition; /* bit position of lsb of red mask (linear modes) */
uint8_t LinGreenMaskSize; /* size of direct color green mask (linear modes) */
uint8_t LinGreenFieldPosition; /* bit position of lsb of green mask (linear modes) */
uint8_t LinBlueMaskSize; /* size of direct color blue mask (linear modes) */
uint8_t LinBlueFieldPosition; /* bit position of lsb of blue mask (linear modes ) */
uint8_t LinRsvdMaskSize; /* size of direct color reserved mask (linear modes) */
uint8_t LinRsvdFieldPosition; /* bit position of lsb of reserved mask (linear modes) */
u32 MaxPixelClock; /* maximum pixel clock (in Hz) for graphics mode */
uint8_t Reserved4[190]; /* remainder of ModeInfoBlock */
} VBE_modeInfo;
struct VBE_modeInfo *modeInfoPointer;
#define modeInfo modeInfoPointer
static u32 *BUFFER = (u32 *) (modeInfo->PhysBasePtr);
// double buffers
u32 *_sbuffers;
u32 _sback = 0;
#define SBUF(_y,_x) \
_sbuffers[((_y) * SCREEN_SIZE) _x]
#define CURRENT &SBUF(0,0)
#define SWAP() (_sback = 1 - _sback)
#define screen_buffer() (_sbuffers[_sback])
static inline void outb(uint16_t port, uint8_t val)
{
asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) );
}
#define bytesPerPixel ((modeInfo->BitsPerPixel 7) / 8)
void screen_set(u32 color,int x,int y) {
u32 physical_address = modeInfo->PhysBasePtr y * modeInfo->LinBytesPerScanLine x * bytesPerPixel;
if (_sbuffers == NULL)
_sbuffers = (u32 *) malloc(sizeof(u32) * 2 * SCREEN_SIZE);
SBUF(_sback,physical_address)=color;
}
static inline uint8_t inb(uint16_t port)
{
uint8_t ret;
asm volatile ( "inb %1, %0"
: "=a"(ret)
: "Nd"(port) );
return ret;
}
const unsigned char font[128-32][8] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U 0020 (space)
/*this bit of code was deleted because it was long/irrelevant */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U 007F
};
static inline void *memcpy(void *dst, const void *src, size_t n)
{
u8 *d = (u8*)dst;
const u8 *s = (const u8*)src;
while (n-- > 0) {
*d = *s ;
}
return d;
}
void screen_swap() {
memcpy(BUFFER, CURRENT, SCREEN_SIZE);
SWAP();
}
unsigned read_pit(void) {
unsigned count = 0;
// al = channel in bits 6 and 7, remaining bits clear
outb(0x43,0b0000000);
count = inb(0x40); // Low byte
count |= inb(0x40)<<8; // High byte
return count;
}
void draw_char(char c, int x, int y, u32 color)
{
const unsigned char *glyph = font[(int)c-32];
for(int cy=0;cy<8;cy ){
for(int cx=0;cx<8;cx ){
if(((int)glyph[cy]&(1<<cx))==(1<<cx)){
screen_set(color,x cx,y cy);
}
}
}
}
void draw_string(const char * s, int x, int y, u32 color) {
int i = 0;
while(s[i] != false) {
draw_char(s[i],x (i*8),y,color);
i ;
}
}
void draw_rect(int pos_x, int pos_y, int w, int h, u32 color) {
for(int y = 0; y<h; y ) {
for(int x = 0; x<w; x ) {
screen_set(color,x pos_x,y pos_y);
}
}
}
static void render(int c0, int c1) {
//draw_rect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,0);
//draw_string("Hello, reader. This is written text.", 100, 180, 16777215);
//draw_string("If this is displayed, my code works.", 100 c0, 100 c1, 16777215);
}
void main(struct VBE_modeInfo *vbe) {
modeInfoPointer = vbe;
int clock = 0;
int incC1 = 0;
int incC0 = 0;
while(true) {
uint16_t scancode = (uint16_t) inb(0x60);
clock ;
if(read_pit()!= 0 && clock == CLOCK_HIT) {
if(scancode == KEY_LEFT) {
incC0--;
}else if(scancode == KEY_RIGHT) {
incC0 ;
}
if(scancode == KEY_DOWN) {
incC1 ;
}else if(scancode == KEY_UP) {
incC1--;
}
clock = 0;
render(incC0,incC1);
screen_swap();
}
}
return;
}
CodePudding user response:
You are only allowed to initialize global variables with:
- a constant value
int i = 5; char* str = "hello world"; int* ptr = &i; struct my_struct = {6, 1, 7}; int my_arr[] = {4, 5, 6};
- a macro expression (only constants and the option below)
#define MY_CONST 5 #define DOUBLE_OF(x) (x * 2) int my_global_var = MY_CONST; int many = DOUBLE_OF(1000); int my_size = sizeof(int);
- a combination of the variants above with operators
int my_combination = 8 MY_CONST sizeof(float);
The problem with your code is, that the compiler may not know the content of modeInfo->PhysBasePtr
(in this case it definitely doesn't know). I don't quite understand what you were trying to do, but maybe you mean:
static u32 *BUFFER = (u32 *) (&modeInfo->PhysBasePtr);
Even if the compiler does not know the content of your buffer, it does know the (relative) memory address of your buffer, because all global variables have a known memory position in their section.
CodePudding user response:
Okay ...
Starting from my answer to your previous question: How can I fix my VBE implementation for my OS?
There are two problems with:
static u32 *BUFFER = (u32 *) (modeInfo->PhysBasePtr);
- Because you changed from
kernel.cpp
tokernel.c
, this is valid C but not valid C - While it was valid C code, [as Eugene pointed out],
modeInfo
wasNULL
The quick fix:
#define BUFFER = ((u32 *) (modeInfo->PhysBasePtr))
However, you still have a problem with double buffering and flicker.
There is the physical frame buffer (i.e.) BUFFER
.
But, you have two offscreen buffers with _sbuffers
.
Herein, we'll call them _sbuffers[0]
and _sbuffers[1]
as if we had defined the buffers as:
u32 *_sbuffers[2];
You need/want only one.
_sback
is the "current" buffer choice. When writing the buffer using screen_set
[and SBUF
], it uses _sbuffers[_sback]
.
However, CURRENT
is defined only to use _sbuffers[0]
.
So, in screen_swap
, on every alternate frame, it is using a stale frame (because it only uses _sbuffers[0]
).
The effect is a "stutter" or "flicker". If you are creating the frames in order:
f0, f1, f2, f3, f4, f5, f6, f7, ...
What you'll [probably] see displayed is:
f0, f0, f2, f2, f4, f4, f6, f6, ...
When the backing buffer _sbuffers
is set with screen_set
, it is slow. So, it is desirable to only update the live screen via screen_swap
(using memcpy
). This is double buffering.
But, we only need/want one backing buffer. Otherwise, we'd need an additional memcpy
to update the contents of the "other" backing buffer.
So, the real fix is to change _sbuffers
to only have one screen image.
Although macros are often a good thing, the sheer number of them was obscuring the issue.
Here is a git diff
. It is made against your b5396d6386356908e88fcd19ec1e6d338f2581b0
commit:
diff --git a/src/kernel.c b/src/kernel.c
index 6215ec4..0d2babd 100644
--- a/src/kernel.c
b/src/kernel.c
@@ -103,14 103,6 @@ struct VBE_modeInfo *modeInfoPointer;
u32 *_sbuffers;
u32 _sback = 0;
-#define SBUF(_y,_x) \
- _sbuffers[((_y) * SCREEN_SIZE) _x]
-
-#define CURRENT &SBUF(0,0)
-#define SWAP() (_sback = 1 - _sback)
-
-#define screen_buffer() (_sbuffers[_sback])
-
static inline void outb(uint16_t port, uint8_t val)
{
asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) );
@@ -119,11 111,11 @@ static inline void outb(uint16_t port, uint8_t val)
#define bytesPerPixel ((modeInfo->BitsPerPixel 7) / 8)
void screen_set(u32 color,int x,int y) {
- u32 physical_address = modeInfo->PhysBasePtr y * modeInfo->LinBytesPerScanLine x * bytesPerPixel;
- if (_sbuffers == NULL)
- _sbuffers = (u32 *) malloc(sizeof(u32) * 2 * SCREEN_SIZE);
u32 physical_address = modeInfo->PhysBasePtr;
physical_address = y * modeInfo->LinBytesPerScanLine;
physical_address = x * bytesPerPixel;
- SBUF(_sback,physical_address)=color;
_sbuffers[physical_address] = color;
}
static inline uint8_t inb(uint16_t port)
@@ -247,8 239,7 @@ static inline void *memcpy(void *dst, const void *src, size_t n)
}
void screen_swap() {
- memcpy(BUFFER, CURRENT, SCREEN_SIZE);
- SWAP();
memcpy(BUFFER, _sbuffers, SCREEN_SIZE);
}
unsigned read_pit(void) {
@@ -302,6 293,8 @@ static void render(int c0, int c1) {
void main(struct VBE_modeInfo *vbe) {
modeInfoPointer = vbe;
_sbuffers = malloc(sizeof(u32) * SCREEN_SIZE);
int clock = 0;
int incC1 = 0;
int incC0 = 0;
Not to worry ... Since we've had trouble with the patch before, here is the full kernel.c
file:
/*
TODO:
-Filesystem
-Mouse Inputs
-Simple GUI
-3d Viewer
-Maybe Link Downloader and Viewer
*/
#define NULL ((void*)0)
#define true 1
#define false 0
typedef unsigned char uint8_t;
typedef unsigned char u8;
typedef unsigned short uint16_t;
typedef unsigned int u32;
typedef u32 size_t;
typedef unsigned long phys_bytes;
#define SCREEN_WIDTH (int)(modeInfo->XResolution)
#define SCREEN_HEIGHT (int)(modeInfo->YResolution)
#define BPP 32
#define SCREEN_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT)
#define FPS 30
#define PIT_HERTZ 1193131.666
#define CLOCK_HIT (int)(PIT_HERTZ/FPS)
#define KEY_LEFT 0x4B
#define KEY_UP 0x48
#define KEY_RIGHT 0x4D
#define KEY_DOWN 0x50
void * malloc(size_t len) {
static size_t curoff = 0;
static char space[1 * 1024 * 1024 * 1024];
void *ptr = NULL;
if ((curoff len) < sizeof(space)) {
ptr = &space[curoff]; curoff = len;
} return ptr;
}
typedef struct VBE_modeInfo{
/* Mandatory information for all VBE revisions */
uint16_t ModeAttributes;
uint8_t WinAAttributes;
uint8_t WinBAttributes;
uint16_t WinGranularity;
uint16_t WinSize;
uint16_t WinASegment;
uint16_t WinBSegment;
phys_bytes WinFuncPtr;
uint16_t BytesPerScanLine;
/* Mandatory information for VBE 1.2 and above */
uint16_t XResolution;
uint16_t YResolution;
uint8_t XCharSize;
uint8_t YCharSize;
uint8_t NumberOfPlanes;
uint8_t BitsPerPixel;
uint8_t NumberOfBanks;
uint8_t MemoryModel;
uint8_t BankSize;
uint8_t NumberOfImagePages;
uint8_t Reserved1;
/* Direct Color fields (required for direct/6 and YUV/7 memory models) */
uint8_t RedMaskSize; /* size of direct color red mask in bits */
uint8_t RedFieldPosition; /* bit position of lsb of red mask */
uint8_t GreenMaskSize; /* size of direct color green mask in bits */
uint8_t GreenFieldPosition; /* bit position of lsb of green mask */
uint8_t BlueMaskSize; /* size of direct color blue mask in bits */
uint8_t BlueFieldPosition; /* bit position of lsb of blue mask */
uint8_t RsvdMaskSize; /* size of direct color reserved mask in bits */
uint8_t RsvdFieldPosition; /* bit position of lsb of reserved mask */
uint8_t DirectColorModeInfo; /* direct color mode attributes */
/* Mandatory information for VBE 2.0 and above */
phys_bytes PhysBasePtr;
uint8_t Reserved2[4];
uint8_t Reserved3[2];
/* Mandatory information for VBE 3.0 and above */
uint16_t LinBytesPerScanLine; /* bytes per scan line for linear modes */
uint8_t BnkNumberOfImagePages; /* number of images for banked modes */
uint8_t LinNumberOfImagePages; /* number of images for linear modes */
uint8_t LinRedMaskSize; /* size of direct color red mask (linear modes) */
uint8_t LinRedFieldPosition; /* bit position of lsb of red mask (linear modes) */
uint8_t LinGreenMaskSize; /* size of direct color green mask (linear modes) */
uint8_t LinGreenFieldPosition; /* bit position of lsb of green mask (linear modes) */
uint8_t LinBlueMaskSize; /* size of direct color blue mask (linear modes) */
uint8_t LinBlueFieldPosition; /* bit position of lsb of blue mask (linear modes ) */
uint8_t LinRsvdMaskSize; /* size of direct color reserved mask (linear modes) */
uint8_t LinRsvdFieldPosition; /* bit position of lsb of reserved mask (linear modes) */
u32 MaxPixelClock; /* maximum pixel clock (in Hz) for graphics mode */
uint8_t Reserved4[190]; /* remainder of ModeInfoBlock */
} VBE_modeInfo;
struct VBE_modeInfo *modeInfoPointer;
#define modeInfo modeInfoPointer
#define BUFFER ((u32 *) (modeInfo->PhysBasePtr))
// double buffers
u32 *_sbuffers;
u32 _sback = 0;
static inline void outb(uint16_t port, uint8_t val)
{
asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) );
}
#define bytesPerPixel ((modeInfo->BitsPerPixel 7) / 8)
void screen_set(u32 color,int x,int y) {
u32 physical_address = modeInfo->PhysBasePtr;
physical_address = y * modeInfo->LinBytesPerScanLine;
physical_address = x * bytesPerPixel;
_sbuffers[physical_address] = color;
}
static inline uint8_t inb(uint16_t port)
{
uint8_t ret;
asm volatile ( "inb %1, %0"
: "=a"(ret)
: "Nd"(port) );
return ret;
}
const unsigned char font[128-32][8] = {
{ 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
};
static inline void *memcpy(void *dst, const void *src, size_t n)
{
u8 *d = (u8*)dst;
const u8 *s = (const u8*)src;
while (n-- > 0) {
*d = *s ;
}
return d;
}
void screen_swap() {
memcpy(BUFFER, _sbuffers, SCREEN_SIZE);
}
unsigned read_pit(void) {
unsigned count = 0;
// al = channel in bits 6 and 7, remaining bits clear
outb(0x43,0b0000000);
count = inb(0x40); // Low byte
count |= inb(0x40)<<8; // High byte
return count;
}
void draw_char(char c, int x, int y, u32 color)
{
const unsigned char *glyph = font[(int)c-32];
for(int cy=0;cy<8;cy ){
for(int cx=0;cx<8;cx ){
if(((int)glyph[cy]&(1<<cx))==(1<<cx)){
screen_set(color,x cx,y cy);
}
}
}
}
void draw_string(const char * s, int x, int y, u32 color) {
int i = 0;
while(s[i] != false) {
draw_char(s[i],x (i*8),y,color);
i ;
}
}
void draw_rect(int pos_x, int pos_y, int w, int h, u32 color) {
for(int y = 0; y<h; y ) {
for(int x = 0; x<w; x ) {
screen_set(color,x pos_x,y pos_y);
}
}
}
static void render(int c0, int c1) {
//draw_rect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,0);
//draw_string("Hello, reader. This is written text.", 100, 180, 16777215);
//draw_string("If this is displayed, my code works.", 100 c0, 100 c1, 16777215);
}
void main(struct VBE_modeInfo *vbe) {
modeInfoPointer = vbe;
_sbuffers = malloc(sizeof(u32) * SCREEN_SIZE);
int clock = 0;
int incC1 = 0;
int incC0 = 0;
while(true) {
uint16_t scancode = (uint16_t) inb(0x60);
clock ;
if(read_pit()!= 0 && clock == CLOCK_HIT) {
if(scancode == KEY_LEFT) {
incC0--;
}else if(scancode == KEY_RIGHT) {
incC0 ;
}
if(scancode == KEY_DOWN) {
incC1 ;
}else if(scancode == KEY_UP) {
incC1--;
}
clock = 0;
render(incC0,incC1);
screen_swap();
}
}
return;
}
Side note: In your commit log, you have a number of sparse messages of the form:
Add files via upload
That's not super descriptive. A one liner would be okay if you're just renaming [as you did].
But, after some time (e.g. six months from now), you'll want a better summary.
As an example, here's a partial commit log from the project I use for some of my SO answers. As with all commit messages, they're a bit cryptic without the context of having the source code:
commit db7cb6b97acef7554618cb71cbcd5459e2e7452b
Author: Craig Estey <censored@by_the.gov>
Date: Sat Jun 4 11:44:13 2022 -0400
- dlkdupdel
- fixed typo in code
commit 79f1919890b025a6bc1c7b1af4d48e5b629af2f7
Author: Craig Estey <censored@by_the.gov>
Date: Fri Jun 3 17:50:24 2022 -0400
- dlkdupdel
- added answer number to Makefile
commit 37fda9cb2c2d308499bf1c4d750e4057398b9846
Author: Craig Estey <censored@by_the.gov>
Date: Thu Jun 2 19:20:19 2022 -0400
- dlkdupdel
- added list_t struct (posted in UPDATE #2)
commit c66e04ec662fa95481590bb11001c4f91ba3db67
Author: Craig Estey <censored@by_the.gov>
Date: Thu Jun 2 19:18:57 2022 -0400
- dlkdupdel
- whole program with diagnostic (posted in UPDATE)
commit 4a7dd901e1128dd3f2bc69304e4c0d7ec5329d8c
Author: Craig Estey <censored@by_the.gov>
Date: Thu Jun 2 19:17:30 2022 -0400
- dlkdupdel
- posted version
commit 8ad6164a90b78bbde847919de3ce4eeea03c1a64
Author: Craig Estey <censored@by_the.gov>
Date: Thu Jun 2 19:16:09 2022 -0400
- dlkdupdel
- first fix (partial function only)
commit 240e5f4c53af062292884e3a31063a36276ac3cd
Author: Craig Estey <censored@by_the.gov>
Date: Thu Jun 2 19:14:53 2022 -0400
- dlkdupdel
- orignal (OP) code
commit 64fa06b1da5a44d06ff1e6c70807a6e00cdeeefa
Author: Craig Estey <censored@by_the.gov>
Date: Wed Jun 1 12:01:44 2022 -0400
- svrfixup
- added getaddrinfo
- added xmsg_status to allow server to show final status to client
- changed xsend/xrecv to retry on EINTR
- added vxcode to interpret return status
- moved child pipe to server_pipe function
- fixed bug in server stop command by clearing SA_RESTART when setting
up signal handler
commit 087d588be67337769a0013295ede96dbf6206b03
Author: Craig Estey <censored@by_the.gov>
Date: Wed May 25 22:23:14 2022 -0400
- svrfixup
- major refactoring to more usual program model
- 3rd posting in UPDATE section
commit c5dd474f35419390b7e1674e7f625837c0f82621
Author: Craig Estey <censored@by_the.gov>
Date: Wed May 25 18:08:41 2022 -0400
- svrfixup
- 2nd posted code
commit 5bfbc62b02c04ef716df21fd2a6bd9171a39c301
Author: Craig Estey <censored@by_the.gov>
Date: Wed May 25 18:05:24 2022 -0400
- added svrfixup
- first posted code
commit 53105b1027b515cb3195b0da620f472aa49ae7ce
Author: Craig Estey <censored@by_the.gov>
Date: Thu May 19 19:09:10 2022 -0400
- mtskbnc
- added automatic retries
commit 2c821006e3a834ec511a09ac6105e6cafbfa120f
Author: Craig Estey <censored@by_the.gov>
Date: Thu May 19 19:07:49 2022 -0400
- mtskbnc
- converted to use single array
commit eddb6bf744d50b0b79e253ec107b19bfa9e57efd
Author: Craig Estey <censored@by_the.gov>
Date: Thu May 19 19:06:51 2022 -0400
- added mtskbnc
commit f6e744f376c9d7be3a9131a5cece4b82782a24d1
Author: Craig Estey <censored@by_the.gov>
Date: Fri Apr 22 10:31:56 2022 -0400
- sparse
- improved ADD message to use UPD
commit 024cf83eec1f753a5c97eb53c3307f5ed0bdb361
Author: Craig Estey <censored@by_the.gov>
Date: Fri Apr 22 10:30:10 2022 -0400
- added sparse matrix code
commit e65496497d91a2d24281a7ac376ac5249a037ca7
Author: Craig Estey <censored@by_the.gov>
Date: Mon Apr 18 13:50:20 2022 -0400
- armstrong
- split up anumdiag script into anxbld, anxcmp, anxdiag, anxgo
- reworked anuixop.rdb to use set* x86 instructions instead of jxx
commit 020e16e527088f71c88e59feb1c253bcb3d232c8
Author: Craig Estey <censored@by_the.gov>
Date: Sat Apr 16 12:20:03 2022 -0400
- dbglib
- added dbgcas.c dbgmsg.c
- added dlk*.c et. al.
- added systty* routines
- renamed some DBGPRT* routines/macros to DBGFLG*
- added spy routines [intercept libc calls]
- dbglib.h
- added dbgpush*/dbgpop* routines
- added table of prefixes for debug environment variables
- added auxv ELF auxiliary vector support
- dbgtype.h
- added ARYFOR* macros
- added UCMP macro
- added SYSFREEME/SYSCLOSEME/SYSFCLOSEME macros
- added u128 typedef
- added tgb support
- evt.c
- converted to use qrng* routines
- added evtprtf support
- evt.h
- converted to qrng
- added additional triggers (e.g. stop on full)
- evtpm
- added support for evtmem* hooks and leak detection
- qrng.c
- reworked from ovrlib version
- added multitask/lock support
- added qrng_buf_* to allow external memcpy in/out of queue
- qrng.h
- added quepair_t
- reworked/renamed qrng_* routines to use quepair_p and rename to qpair_*
- tsk.c
- added tsksetup
- added master control (e.g. tsm)
- tsk.h
- added tskmst