Update project organization
This commit is contained in:
parent
aea7368d46
commit
da5ff236bb
|
@ -58,3 +58,4 @@ build/
|
|||
.tests
|
||||
.old
|
||||
*.g1a
|
||||
debug_bin
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Vhex Kernel
|
||||
|
||||
Vhex is a kernel which provide development and retro ingenierie environment for fx9860g.
|
||||
Vhex is a kernel which provide retro ingenierie environment for the fx9860g.
|
||||
The Casio's OS code is not open-source, but we can read the binary for understand his working.
|
||||
There are in particular the syscalls, OS's functions that can be called as a library by the add-ins, which are a gold mine of clues about the functioning of the material.
|
||||
|
||||
|
@ -9,6 +9,9 @@ There are in particular the syscalls, OS's functions that can be called as a lib
|
|||
* Loader ELF
|
||||
* Scheduler (not prehemptive yet)
|
||||
* Driver (EEPROM (read), screen, keyboard, timers)
|
||||
* Syscall
|
||||
* Virtual File System
|
||||
* File System Ext2 on RAM
|
||||
|
||||
## Building
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef __KERNEL_DEVICES_EARLYTERM_H__
|
||||
# define __KERNEL_DEVICES_EARLYTERM_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <lib/display.h>
|
||||
|
||||
// Wait for debug (dirty)
|
||||
// TODO: use earlyterm_read() to wait key event ?
|
||||
#define DBG_WAIT for(int i = 0 ; i < 3000000 ; i++)
|
||||
|
||||
// Internal earlyterm device struc
|
||||
struct earlyterm
|
||||
{
|
||||
// Internal object used by the
|
||||
// drawing lib
|
||||
display_t display;
|
||||
|
||||
// Cursor part, we use only the X
|
||||
// axis because we scroll the vram when
|
||||
// the line overflow or new line char
|
||||
// involved.
|
||||
struct {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
struct {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} max;
|
||||
} cursor;
|
||||
};
|
||||
|
||||
|
||||
// Primitives
|
||||
extern int earlyterm_init(void);
|
||||
extern void earlyterm_clear(void);
|
||||
extern void earlyterm_write(const char *format, ...);
|
||||
|
||||
#endif /*__KERNEL_DEVICES_EARLYTERM_H__*/
|
|
@ -5,19 +5,25 @@
|
|||
#include <stdint.h>
|
||||
#include <kernel/drivers/screen.h>
|
||||
#include <kernel/util/types.h>
|
||||
#include <kernel/util/draw.h>
|
||||
#include <lib/display.h>
|
||||
|
||||
// Define default buffer size.
|
||||
// TODO: remove me ?
|
||||
#define TTY_BUFFER_LINES (DISPLAY_VCHAR_MAX * 3)
|
||||
#define TTY_BUFFER_COLUMNS (DISPLAY_HCHAR_MAX)
|
||||
//#define TTY_BUFFER_LINES (DISPLAY_VCHAR_MAX * 3)
|
||||
//#define TTY_BUFFER_COLUMNS (DISPLAY_HCHAR_MAX)
|
||||
|
||||
// Define TTY major
|
||||
#define TTY_DEV_MAJOR (4)
|
||||
|
||||
struct tty_s
|
||||
{
|
||||
char buffer[TTY_BUFFER_LINES + 1][TTY_BUFFER_COLUMNS + 1];
|
||||
// Internal buffers
|
||||
struct {
|
||||
char input[256];
|
||||
char **output;
|
||||
} buffers;
|
||||
|
||||
// Cursor informations
|
||||
struct {
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
|
@ -27,10 +33,9 @@ struct tty_s
|
|||
} max;
|
||||
} cursor;
|
||||
|
||||
/*struct {
|
||||
ssize_t (*write)(const void *buffer, size_t count);
|
||||
ssize_t (*read)(void *buffer, size_t count);
|
||||
} primitives;*/
|
||||
// Object used by the drawing library.
|
||||
// It's store video ram and font informations
|
||||
display_t disp;
|
||||
};
|
||||
|
||||
// internal strct used by the TTY read primitives
|
||||
|
|
|
@ -4,8 +4,15 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Define screen informations.
|
||||
#define DISPLAY_SCREEN_WIDTH (128)
|
||||
#define DISPLAY_SCREEN_HEIGHT (64)
|
||||
// Internal enumeration for the
|
||||
// screen getter
|
||||
typedef enum {
|
||||
SCREEN_WIDTH,
|
||||
SCREEN_HEIGHT
|
||||
} screen_getter_t;
|
||||
|
||||
// Internal hardware abstract
|
||||
extern size_t screen_get(screen_getter_t getter);
|
||||
extern void (*screen_update)(void *vram);
|
||||
|
||||
#endif /*__KERNEL_DRIVERS_SCREEN_H__*/
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
#include <kernel/util/elf.h>
|
||||
|
||||
// Function
|
||||
extern void *loader(const char *path, struct process *process);
|
||||
extern int loader(struct process *process, const char *path);
|
||||
extern int loader_get_header(FILE *file, Elf32_Ehdr *header);
|
||||
extern void *loader_load_image(FILE *file, Elf32_Ehdr *header, struct process *process);
|
||||
extern int loader_load_image(struct process *process, FILE *file, Elf32_Ehdr *header);
|
||||
|
||||
#endif /*__KERNEL_LOADER_H__*/
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
#ifndef __KERNEL_UTIL_DEBUG_H__
|
||||
# define __KERNEL_UTIL_DEBUG_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <kernel/util/draw.h>
|
||||
|
||||
// Wait debug (dirty)
|
||||
#define DBG_WAIT for(int i = 0 ; i < 3000000 ; i++)
|
||||
|
||||
// Prototype
|
||||
void printk(int x, int y, char const *str, ...);
|
||||
|
||||
#endif /*__KERNEL_UTIL_DEBUG_H__*/
|
|
@ -1,51 +0,0 @@
|
|||
#ifndef __KERNEL_UTIL_DRAW_H__
|
||||
# define __KERNEL_UTIL_DRAW_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <kernel/drivers/screen.h>
|
||||
|
||||
// Define the (hardcoded) font bitmap informations.
|
||||
#define KERNEL_FONT_BITMAP_WIDTH (127) // Bitmap width
|
||||
#define KERNEL_FONT_BITMAP_HEIGHT (23) // Bitmap height
|
||||
#define KERNEL_FONT_BITMAP_CWIDTH (4) // Character width (bitmap)
|
||||
#define KERNEL_FONT_BITMAP_CHEIGHT (6) // Character height (bitmap)
|
||||
#define KERNEL_FONT_REAL_WIDTH (3) // Charater width (real)
|
||||
#define KERNEL_FONT_REAL_HEIGHT (5) // Character height (real)
|
||||
#define KERNEL_FONT_NB_CHAR_X ((KERNEL_FONT_BITMAP_WIDTH / KERNEL_FONT_BITMAP_CWIDTH) + 1)
|
||||
#define KERNEL_FONT_NB_CHAR_Y ((KERNEL_FONT_BITMAP_HEIGHT / KERNEL_FONT_BITMAP_CHEIGHT) + 1)
|
||||
|
||||
// Define Number of vertical lines
|
||||
// and horizontal lines.
|
||||
// TODO: move me to <kernel/drivers/screen.h> ?
|
||||
#define DISPLAY_VCHAR_MAX (DISPLAY_SCREEN_HEIGHT / (KERNEL_FONT_REAL_HEIGHT + 1))
|
||||
#define DISPLAY_HCHAR_MAX (DISPLAY_SCREEN_WIDTH / (KERNEL_FONT_REAL_WIDTH + 1))
|
||||
|
||||
|
||||
|
||||
// Internal struct used to draw
|
||||
// the ASCII character.
|
||||
struct font_block_s
|
||||
{
|
||||
int16_t height;
|
||||
int16_t width;
|
||||
struct {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
} bitmap;
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Prototype
|
||||
extern void kvram_clear(void);
|
||||
extern void kvram_display(void);
|
||||
extern void kvram_scroll(int lines);
|
||||
extern void kvram_reverse(int x, int y, int width, int height);
|
||||
extern void kvram_clr_str_area(int x, int y, int width, int height);
|
||||
extern void kvram_print(int x, int y, const char *string, size_t len);
|
||||
extern void kvram_ascii(int x, int y, char const c);
|
||||
|
||||
#endif /*__KERNEL_UTIL_DRAW_H__*/
|
|
@ -1,31 +0,0 @@
|
|||
#ifndef __KERNEL_UTIL_STRING_H__
|
||||
# define __KERNEL_UTIL_STRING_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* memset() - fill memory with a constant byte. */
|
||||
extern void *memset(void *s, int c, size_t n);
|
||||
extern void *memcpy(void *dest, const void *src, size_t n);
|
||||
|
||||
/* strcat() - concatenate two string */
|
||||
extern char *strcat(char *dest, char const *src);
|
||||
|
||||
/* strcmp() - compare two strings */
|
||||
extern int strcmp(const char *s1, const char *s2);
|
||||
extern int strncmp(const char *s1, const char *s2, size_t n);
|
||||
|
||||
/* strcpy(), strncpy() - copy a string. */
|
||||
extern char *strncpy(char *dest, char const *str, size_t size);
|
||||
extern char *strcpy(char *dest, char const *src);
|
||||
|
||||
/* strlen - calculate the lenght of a string. */
|
||||
extern size_t strnlen(char const *str, size_t maxlen);
|
||||
extern size_t strlen(char const *str);
|
||||
|
||||
/* strchr - find the first / last occurent of the char c */
|
||||
extern char *strchr(const char *s1, int c);
|
||||
extern char *strchrnul(const char *s1, int c);
|
||||
extern char *strrchr(const char *s1, int c);
|
||||
|
||||
#endif /*__KERNEL_UTIL_STRING_H__*/
|
|
@ -4,13 +4,61 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Draw primtives
|
||||
extern void dclear(void);
|
||||
extern void dclr_str_area(int x, int y, int with, int height);
|
||||
extern void dprint(int x, int y, char const *str, ...);
|
||||
extern void dascii(int x, int y, char const c);
|
||||
extern void dreverse(int x, int y, int width, int height);
|
||||
extern void dscroll(int line);
|
||||
extern void dupdate(void);
|
||||
// Internal struct used in each draw function
|
||||
typedef struct display_s
|
||||
{
|
||||
uint32_t vram[256];
|
||||
struct font_s *font;
|
||||
struct {
|
||||
size_t width;
|
||||
size_t height;
|
||||
} display;
|
||||
|
||||
// Internal pre-calculated value
|
||||
int nb_char_width;
|
||||
} display_t;
|
||||
|
||||
// Internal struct used to define font structure object.
|
||||
// TODO: move me ?
|
||||
struct font_s
|
||||
{
|
||||
// Bitmap informations
|
||||
struct {
|
||||
uint8_t width;
|
||||
uint8_t height;
|
||||
uint8_t cwidth;
|
||||
uint8_t cheight;
|
||||
uint8_t *raw;
|
||||
} bitmap;
|
||||
|
||||
// Character information
|
||||
struct {
|
||||
uint8_t width;
|
||||
uint8_t height;
|
||||
} font;
|
||||
};
|
||||
|
||||
// Internal struct used to draw
|
||||
// the ASCII character.
|
||||
struct font_block_s
|
||||
{
|
||||
int16_t height;
|
||||
int16_t width;
|
||||
struct {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
} bitmap;
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
};
|
||||
|
||||
// Draw primitives
|
||||
extern int dopen(display_t *disp, const char *fontname);
|
||||
extern void dclear(display_t *disp);
|
||||
extern void dascii(display_t *disp, int row, int colomn, char const c);
|
||||
extern size_t dprint(display_t *disp, int x, int y, char const *str, ...);
|
||||
extern void dscroll(display_t *disp, int line);
|
||||
extern void dreverse(display_t *disp, int x, int y, int width, int height);
|
||||
extern void dupdate(display_t *disp);
|
||||
|
||||
#endif /*__LIB_DISPLAY_H__*/
|
||||
|
|
|
@ -5,21 +5,25 @@
|
|||
#include <stddef.h>
|
||||
|
||||
/* memset() - fill memory with a constant byte. */
|
||||
void *memset(void *s, int c, size_t n);
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
extern void *memset(void *s, int c, size_t n);
|
||||
extern void *memcpy(void *dest, const void *src, size_t n);
|
||||
|
||||
/* strcat() - concatenate two string */
|
||||
char *strcat(char *dest, char const *src);
|
||||
extern char *strcat(char *dest, char const *src);
|
||||
|
||||
/* strcmp() - compare two strings */
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
extern int strcmp(const char *s1, const char *s2);
|
||||
extern int strncmp(const char *s1, const char *s2, size_t n);
|
||||
|
||||
/* strcpy(), strncpy() - copy a string. */
|
||||
char *strncpy(char *dest, char const *str, size_t size);
|
||||
char *strcpy(char *dest, char const *src);
|
||||
extern char *strncpy(char *dest, char const *str, size_t size);
|
||||
extern char *strcpy(char *dest, char const *src);
|
||||
|
||||
/* strlen - calculate the lenght of a string. */
|
||||
size_t strnlen(char const *str, size_t maxlen);
|
||||
size_t strlen(char const *str);
|
||||
extern size_t strnlen(char const *str, size_t maxlen);
|
||||
extern size_t strlen(char const *str);
|
||||
|
||||
/* strrchr() - find the last occurent of a byte */
|
||||
extern char *strrchr(const char *s, int c);
|
||||
|
||||
#endif /*__STRING_H__*/
|
||||
|
|
|
@ -20,6 +20,7 @@ NAME := vhex
|
|||
EXEC := $(OUTPUT)/$(NAME).g1a
|
||||
LDFLAG := -T $(NAME).ld
|
||||
MEMORY_MAP := $(DEBUG)/$(NAME).map
|
||||
LIBS := -L../lib -lgcc -lstring -ldisplay
|
||||
ICON := icon.bmp
|
||||
|
||||
|
||||
|
@ -46,10 +47,10 @@ OBJ := $(patsubst ._%,$(BUILD)/%.o,$(subst /,_,$(basename $(SRC))))
|
|||
##---
|
||||
## General rules
|
||||
##---
|
||||
all: | $(BUILD) $(DEBUG) $(OUTPUT) $(EXEC)
|
||||
all: $(OUTPUT) $(EXEC)
|
||||
|
||||
$(EXEC): $(OBJ)
|
||||
$(CC) -Wl,-M $(LDFLAG) $(CFLAGS) -o $(DEBUG)/$(NAME).elf $(OBJ) $(HEADER) -lgcc -L../lib -l_display > $(MEMORY_MAP)
|
||||
$(EXEC): $(OBJ) | $(DEBUG)
|
||||
$(CC) -Wl,-M $(LDFLAG) $(CFLAGS) -o $(DEBUG)/$(NAME).elf $(OBJ) $(HEADER) $(LIBS) > $(MEMORY_MAP)
|
||||
$(OBJCOPY) -R .comment -R .bss -O binary $(DEBUG)/$(NAME).elf $(DEBUG)/$(NAME).bin
|
||||
$(WRAPPER) $(DEBUG)/$(NAME).bin -o $@ -i $(ICON)
|
||||
|
||||
|
@ -84,7 +85,7 @@ sec:
|
|||
## Automated rules
|
||||
##---
|
||||
define rule-src
|
||||
$(patsubst ._%,$(BUILD)/%.o,$(subst /,_,$(basename $1))): $1
|
||||
$(patsubst ._%,$(BUILD)/%.o,$(subst /,_,$(basename $1))): $1 | $(BUILD)
|
||||
@ printf "compiling $(white)$$<$(nocolor)..."
|
||||
@ $(CC) $(CFLAGS) -o $$@ -c $$< $(HEADER) -lgcc
|
||||
@ printf "$(green)[ok]$(nocolor)\n"
|
||||
|
|
|
@ -1,20 +1,26 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
// Internal helpers
|
||||
#include <kernel/util/types.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <kernel/util/casio.h>
|
||||
// Modules
|
||||
#include <kernel/context.h>
|
||||
#include <kernel/process.h>
|
||||
#include <kernel/syscall.h>
|
||||
#include <kernel/scheduler.h>
|
||||
#include <kernel/loader.h>
|
||||
// Devices
|
||||
#include <kernel/devices/tty.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
// File System
|
||||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/fs/stat.h>
|
||||
#include <kernel/fs/smemfs.h>
|
||||
#include <kernel/fs/gladfs.h>
|
||||
#include <kernel/loader.h>
|
||||
#include <kernel/devices/tty.h>
|
||||
// Libs
|
||||
#include <lib/display.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
// Internal symbols
|
||||
mpu_t current_mpu = MPU_UNKNOWN;
|
||||
|
@ -78,7 +84,7 @@ static void rom_explore(volatile void *rom, int32_t size)
|
|||
/* section_execute() - Used to execute contructors and destructors */
|
||||
static void section_execute(void *bsection, void *esection)
|
||||
{
|
||||
while ((uint32_t)bsection < (uint32_t)esection)
|
||||
while ((uintptr_t)bsection < (uintptr_t)esection)
|
||||
{
|
||||
((void (*)(void))*((uint32_t*)bsection))();
|
||||
bsection = (void*)((uint32_t)bsection + 4);
|
||||
|
@ -90,9 +96,6 @@ static void section_execute(void *bsection, void *esection)
|
|||
__attribute__((section(".pretext")))
|
||||
int start(void)
|
||||
{
|
||||
extern uint32_t vram[256];
|
||||
int error;
|
||||
|
||||
//--
|
||||
// Bootstrap part !
|
||||
//--
|
||||
|
@ -120,6 +123,16 @@ int start(void)
|
|||
// before switching the VBR.
|
||||
rom_explore(&brom, (int32_t)&srom);
|
||||
|
||||
// Start early terminal device
|
||||
// This device is used by the kernel to display
|
||||
// some logs on screen
|
||||
if (earlyterm_init() != 0)
|
||||
return (-1);
|
||||
earlyterm_clear();
|
||||
earlyterm_write("Kernel initialisation...\n");
|
||||
|
||||
|
||||
|
||||
// Save Casio's hardware context and set
|
||||
// Vhex hardware context.
|
||||
// @note:
|
||||
|
@ -130,6 +143,7 @@ int start(void)
|
|||
// And this is why between each `atomic_start`
|
||||
// and `atomic_end()` the code *SHOULD* be
|
||||
// exception safe.
|
||||
earlyterm_write("Environment switch...\n");
|
||||
atomic_start();
|
||||
fx9860_context_save(&casio_context);
|
||||
vhex_context_set();
|
||||
|
@ -140,14 +154,17 @@ int start(void)
|
|||
//---
|
||||
|
||||
// Internal FS init !
|
||||
earlyterm_write("Initialize File System...\n");
|
||||
gladfs_initialize();
|
||||
smemfs_initialize();
|
||||
|
||||
// Initilize Virtual File System
|
||||
earlyterm_write("Init. Virtual File System...\n");
|
||||
vfs_register_filesystem(&gladfs_filesystem);
|
||||
vfs_register_filesystem(&smemfs_filesystem);
|
||||
|
||||
// Creat initial file tree
|
||||
earlyterm_write("Create Filesystem Hierarchy...\n");
|
||||
vfs_mount(NULL, NULL, "gladfs", VFS_MOUNT_ROOT, NULL);
|
||||
vfs_mkdir("/dev", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
vfs_mkdir("/home", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||
|
@ -156,41 +173,43 @@ int start(void)
|
|||
vfs_mount(NULL, "/mnt/smemfs", "smemfs", /*MS_RDONLY*/0, NULL);
|
||||
|
||||
// Add devices
|
||||
earlyterm_write("Add devices...\n");
|
||||
vfs_mknod("/dev/tty", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH,
|
||||
dev_make_major(TTY_DEV_MAJOR));
|
||||
|
||||
|
||||
// Test mode !
|
||||
//extern void kernel_test(void);
|
||||
//kernel_test();
|
||||
|
||||
//---
|
||||
// Start first process !
|
||||
//---
|
||||
|
||||
|
||||
// Create first process: Vhex.
|
||||
struct process *vhex_process = process_create("Vhex");
|
||||
if (vhex_process == NULL)
|
||||
//earlyterm_write("Create first process...\n");
|
||||
//struct process *vhex_process = process_create("Vhex");
|
||||
/*if (vhex_process == NULL)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "Vhex fatal error !");
|
||||
printk(0, 1, "First process error !");
|
||||
printk(0, 2, "Wait manual reset...");
|
||||
kvram_display();
|
||||
earlyterm_clear();
|
||||
earlyterm_write("Vhex fatal error !\n");
|
||||
earlyterm_write("First process error !\n");
|
||||
earlyterm_write("Press [MENU] key...\n");
|
||||
while (1) { __asm__ volatile ("sleep"); }
|
||||
}
|
||||
}*/
|
||||
|
||||
// Load programe.
|
||||
//vhex_process->context.spc = (uint32_t)&kernel_test;
|
||||
vhex_process->context.spc = (uint32_t)loader("/mnt/smemfs/VHEX/shell.elf", vhex_process);
|
||||
if (vhex_process->context.spc == 0x00000000)
|
||||
//vhex_process->context.spc = (uint32_t)loader("/mnt/smemfs/VHEX/shell.elf", vhex_process);
|
||||
//if (vhex_process->context.spc == 0x00000000)
|
||||
earlyterm_write("Create first process...\n");
|
||||
struct process *vhex_process = process_create("Vhex");
|
||||
if (vhex_process == NULL || loader(vhex_process, "/mnt/smemfs/VHEX/shell.elf") != 0)
|
||||
{
|
||||
// Display message.
|
||||
kvram_clear();
|
||||
printk(0, 0, "Vhex fatal error !");
|
||||
printk(0, 1, "File \"VHEX/shell.elf\" not found !");
|
||||
printk(0, 2, "Press [MENU key]...");
|
||||
kvram_display();
|
||||
earlyterm_clear();
|
||||
earlyterm_write("Vhex fatal error !\n");
|
||||
earlyterm_write("Unable to create the first process !\n");
|
||||
if (vhex_process->context.spc == 0xffffffff)
|
||||
earlyterm_write("process_create() error\n");
|
||||
else
|
||||
earlyterm_write("File \"VHEX/shell.elf\" not found !");
|
||||
earlyterm_write("Press [MENU key]...");
|
||||
|
||||
// Restore Casio context.
|
||||
fx9860_context_restore(&casio_context);
|
||||
|
@ -200,7 +219,8 @@ int start(void)
|
|||
// @note: GetKey will call Bdisp_PutDD_VRAM(),
|
||||
// so save the current internal Video RAM data into
|
||||
// Casio's VRAM.
|
||||
memcpy(casio_Bdisp_GetVRAM(), vram, 1024);
|
||||
extern struct earlyterm earlyterm;
|
||||
memcpy(casio_Bdisp_GetVRAM(), earlyterm.display.vram, 1024);
|
||||
|
||||
// Wait MENU key.
|
||||
unsigned int key;
|
||||
|
@ -210,24 +230,16 @@ int start(void)
|
|||
}
|
||||
}
|
||||
|
||||
// DEBUG !
|
||||
kvram_clear();
|
||||
printk(0, 0, "Initialize scheduler !");
|
||||
printk(0, 1, "Try to start sceduler...");
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
|
||||
// Initialize sheduler !!
|
||||
//---
|
||||
// Initialize sheduler !!
|
||||
//---
|
||||
earlyterm_write("Initialize scheduler...\n");
|
||||
sched_initialize();
|
||||
sched_add_task(vhex_process);
|
||||
sched_start();
|
||||
|
||||
// normally the kernel SHOULD / CAN not arrive here.
|
||||
kvram_clear();
|
||||
printk(0, 0, "Kernel job fini !");
|
||||
kvram_display();
|
||||
while (1)
|
||||
{
|
||||
__asm__ volatile ("sleep");
|
||||
}
|
||||
earlyterm_write("Kernel job fini !");
|
||||
while (1) { __asm__ volatile ("sleep"); }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
#include <kernel/devices/earlyterm.h>
|
||||
#include <lib/display.h>
|
||||
|
||||
/* earlyterm_clear() - clear internal vram and reset cursor position */
|
||||
void earlyterm_clear(void)
|
||||
{
|
||||
extern struct earlyterm earlyterm;
|
||||
|
||||
// Clear video ram
|
||||
dclear(&earlyterm.display);
|
||||
|
||||
// Reset cursor
|
||||
earlyterm.cursor.x = 0;
|
||||
earlyterm.cursor.y = 0;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#include <kernel/devices/earlyterm.h>
|
||||
#include <kernel/drivers/screen.h>
|
||||
|
||||
// Internal globals
|
||||
struct earlyterm earlyterm;
|
||||
|
||||
// earlyterm_init()
|
||||
// Initialize internal early terminal symbols
|
||||
int earlyterm_init(void)
|
||||
{
|
||||
// Get internal vram and font
|
||||
// TODO: return menu
|
||||
if (dopen(&earlyterm.display, "default") != 0)
|
||||
return (-1);
|
||||
|
||||
// Generate cursor informations
|
||||
earlyterm.cursor.x = 0;
|
||||
earlyterm.cursor.max.x = screen_get(SCREEN_WIDTH);
|
||||
earlyterm.cursor.max.x /= earlyterm.display.font->font.width + 1;
|
||||
|
||||
earlyterm.cursor.max.y = screen_get(SCREEN_HEIGHT);
|
||||
earlyterm.cursor.max.y /= earlyterm.display.font->font.height + 1;
|
||||
earlyterm.cursor.y = 0;
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
#include <kernel/devices/earlyterm.h>
|
||||
#include <kernel/drivers/screen.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* earlyterm_vertical_update() - Check / update device vertical cursor */
|
||||
static void earlyterm_vertical_update(struct earlyterm *earlyterm)
|
||||
{
|
||||
// Check if we can move the cursor
|
||||
if (earlyterm->cursor.y + 1 < earlyterm->cursor.max.y) {
|
||||
earlyterm->cursor.y = earlyterm->cursor.y + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Other wise scroll the vram
|
||||
dscroll(&earlyterm->display, earlyterm->display.font->font.height + 1);
|
||||
}
|
||||
|
||||
/* earlyterm_horizontal_update() - Check / update earlyterm horizotal cursor */
|
||||
static int earlyterm_horizontal_update(struct earlyterm *earlyterm)
|
||||
{
|
||||
earlyterm->cursor.x = earlyterm->cursor.x + 1;
|
||||
if (earlyterm->cursor.x >= earlyterm->cursor.max.x)
|
||||
{
|
||||
earlyterm_vertical_update(earlyterm);
|
||||
earlyterm->cursor.x = 0;
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* print_base() - display number in base (0~16)*/
|
||||
static void print_base(struct earlyterm *earlyterm, uint32_t nb,
|
||||
int base, int digits_min)
|
||||
{
|
||||
char hex[] = "0123456789abcdef";
|
||||
char buffer[16];
|
||||
int digits;
|
||||
|
||||
// Generate string (reverse)
|
||||
digits = 0;
|
||||
while (digits < digits_min || nb != 0)
|
||||
{
|
||||
buffer[digits++] = hex[nb % base];
|
||||
nb = nb / base;
|
||||
}
|
||||
|
||||
// Display string.
|
||||
while (--digits >= 0)
|
||||
{
|
||||
dascii(&earlyterm->display, earlyterm->cursor.x,
|
||||
earlyterm->cursor.y, buffer[digits]);
|
||||
earlyterm_horizontal_update(earlyterm);
|
||||
}
|
||||
}
|
||||
|
||||
/* line_discipline() - Check all "special" char */
|
||||
static int line_discipline(struct earlyterm *earlyterm, char n)
|
||||
{
|
||||
// New line
|
||||
if (n == '\n')
|
||||
{
|
||||
earlyterm->cursor.x = 0;
|
||||
earlyterm_vertical_update(earlyterm);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
// earlyterm_write() - printf wrapper for early terminal device
|
||||
// TODO: update me... x_x
|
||||
void earlyterm_write(const char *format, ...)
|
||||
{
|
||||
extern struct earlyterm earlyterm;
|
||||
int32_t nb;
|
||||
va_list ap;
|
||||
int i;
|
||||
|
||||
// Atomic start
|
||||
atomic_start();
|
||||
|
||||
// Get starting variable args
|
||||
va_start(ap, format);
|
||||
|
||||
// Walk into string and display character by character
|
||||
i = -1;
|
||||
while (format[++i] != '\0')
|
||||
{
|
||||
// Check line discipline
|
||||
if (line_discipline(&earlyterm, format[i]) != 0)
|
||||
continue;
|
||||
|
||||
// String format "simple"
|
||||
if (format[i] == '%')
|
||||
{
|
||||
if (format[i + 1] == 'd' || format[i + 1] == 'x')
|
||||
{
|
||||
// Check negative value
|
||||
// FIXME: negative error (max)
|
||||
nb = va_arg(ap, int32_t);
|
||||
if (nb < 0 && format[i + 1] == 'd')
|
||||
{
|
||||
nb = 0 - nb;
|
||||
dascii(&earlyterm.display, earlyterm.cursor.x, earlyterm.cursor.y, '-');
|
||||
earlyterm_horizontal_update(&earlyterm);
|
||||
}
|
||||
print_base(&earlyterm, nb, (format[i + 1] == 'd') ? 10 : 16, 1);
|
||||
i = i + 1;
|
||||
continue;
|
||||
}
|
||||
if ((format[i + 1] == '#' && format[i + 2] == 'x') || format[i + 1] == 'p')
|
||||
{
|
||||
// add @ if 'p' (pointer)
|
||||
if (format[i + 1] == 'p')
|
||||
{
|
||||
dascii(&earlyterm.display, earlyterm.cursor.x, earlyterm.cursor.y, '@');
|
||||
earlyterm_horizontal_update(&earlyterm);
|
||||
}
|
||||
|
||||
// Add "0x"
|
||||
dascii(&earlyterm.display, earlyterm.cursor.x, earlyterm.cursor.y, '0');
|
||||
earlyterm_horizontal_update(&earlyterm);
|
||||
dascii(&earlyterm.display, earlyterm.cursor.x, earlyterm.cursor.y, 'x');
|
||||
earlyterm_horizontal_update(&earlyterm);
|
||||
|
||||
// Get value
|
||||
nb = va_arg(ap, uint32_t);
|
||||
print_base(&earlyterm, nb, 16, 8);
|
||||
|
||||
// Update cursor
|
||||
i = (format[i + 1] == '#') ? i + 2 : i + 1;
|
||||
continue;
|
||||
}
|
||||
if (format[i + 1] == 's')
|
||||
{
|
||||
nb = va_arg(ap, uint32_t) - 1;
|
||||
while (*(char*)(++nb) != '\0')
|
||||
{
|
||||
if (line_discipline(&earlyterm, *(char*)nb) != 0)
|
||||
continue;
|
||||
dascii(&earlyterm.display, earlyterm.cursor.x, earlyterm.cursor.y, *(char*)nb);
|
||||
earlyterm_horizontal_update(&earlyterm);
|
||||
}
|
||||
i = i + 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Default, display character
|
||||
dascii(&earlyterm.display, earlyterm.cursor.x, earlyterm.cursor.y, format[i]);
|
||||
earlyterm_horizontal_update(&earlyterm);
|
||||
}
|
||||
|
||||
// Display vram
|
||||
screen_update(earlyterm.display.vram);
|
||||
|
||||
// End of variodic args.
|
||||
va_end(ap);
|
||||
|
||||
// Atomic stop
|
||||
atomic_stop();
|
||||
}
|
|
@ -7,7 +7,7 @@ DEVICE(tty) = {
|
|||
.file_op = {
|
||||
.read = (void *)&tty_read,
|
||||
.write =(void *)&tty_write,
|
||||
.ioctl = &tty_ioctl
|
||||
.ioctl = NULL
|
||||
},
|
||||
.close = &tty_close
|
||||
};
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
#include <kernel/devices/tty.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
void tty_ioctl(void *inode, uint32_t cmd, ...)
|
||||
{
|
||||
struct tty_s *tty;
|
||||
va_list ap;
|
||||
|
||||
// Start atomic operation
|
||||
atomic_start();
|
||||
|
||||
tty = inode;
|
||||
va_start(ap, cmd);
|
||||
switch (cmd)
|
||||
{
|
||||
case TTY_IOCTL_GETDX:
|
||||
{
|
||||
int *dx = va_arg(ap, int*);
|
||||
*dx = tty->cursor.x * (KERNEL_FONT_REAL_WIDTH + 1);
|
||||
break;
|
||||
}
|
||||
case TTY_IOCTL_GETDY:
|
||||
{
|
||||
int *dy = va_arg(ap, int*);
|
||||
int start = tty->cursor.y;
|
||||
int saved_start;
|
||||
int line = -1;
|
||||
|
||||
while (++line < DISPLAY_VCHAR_MAX - 1)
|
||||
{
|
||||
// Update check line.
|
||||
saved_start = start;
|
||||
start = (start - 1 < 0) ? tty->cursor.max.y : start - 1;
|
||||
|
||||
// Check if the line exist.
|
||||
if (tty->buffer[start][0] == '\0')
|
||||
{
|
||||
start = saved_start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*dy = line * (KERNEL_FONT_REAL_HEIGHT + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
// Stop atomic operation
|
||||
atomic_stop();
|
||||
}
|
|
@ -1,7 +1,22 @@
|
|||
#include <kernel/devices/tty.h>
|
||||
#include <kernel/memory.h>
|
||||
|
||||
int tty_close(void *inode)
|
||||
{
|
||||
// Do nothing for now.
|
||||
struct tty_s *tty;
|
||||
int line;
|
||||
|
||||
// Get tty object
|
||||
tty = inode;
|
||||
|
||||
// Free'd all allocated memory for the
|
||||
// output buffer
|
||||
line = tty->cursor.max.y;
|
||||
while (line >= 0)
|
||||
pm_free(tty->buffers.output[line]);
|
||||
pm_free(tty->buffers.output);
|
||||
|
||||
// Free'd tty object
|
||||
pm_free(tty);
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -1,29 +1,64 @@
|
|||
#include <kernel/devices/tty.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
#include <kernel/drivers/screen.h>
|
||||
#include <kernel/memory.h>
|
||||
#include <lib/display.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
// Internal TTY object.
|
||||
static struct tty_s tty;
|
||||
|
||||
//TODO: MULTIPLE OPEN !!!!
|
||||
//TODO: SHARED TTY DEVICE !!!!
|
||||
void *tty_open(dev_t major, dev_t minor)
|
||||
{
|
||||
int lines;
|
||||
struct tty_s *tty;
|
||||
int line;
|
||||
|
||||
// TODO: handle major / minor ?
|
||||
// TODO: handle major / minor !!
|
||||
(void)major;
|
||||
(void)minor;
|
||||
|
||||
// Try to allocate tty object
|
||||
tty = (struct tty_s*)pm_alloc(sizeof(struct tty_s));
|
||||
if (tty == NULL)
|
||||
return (NULL);
|
||||
|
||||
// Initialize TTY cursor.
|
||||
tty.cursor.x = 0;
|
||||
tty.cursor.y = 0;
|
||||
tty.cursor.max.x = TTY_BUFFER_COLUMNS;
|
||||
tty.cursor.max.y = TTY_BUFFER_LINES;
|
||||
// Get the font used by the tty.
|
||||
if (dopen(&tty->disp, "default") != 0)
|
||||
{
|
||||
pm_free(tty);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// Initialize TTY buffer.
|
||||
// TODO: user can set dynamicaly the TTY buffer size ?
|
||||
lines = TTY_BUFFER_LINES;
|
||||
while (--lines >= 0)
|
||||
memset(tty.buffer[lines], '\0', TTY_BUFFER_COLUMNS);
|
||||
return (&tty);
|
||||
// Generate formated output buffer indicator
|
||||
tty->cursor.max.x = screen_get(SCREEN_WIDTH) / (tty->disp.font->font.width + 1);
|
||||
tty->cursor.max.y = screen_get(SCREEN_HEIGHT) / (tty->disp.font->font.height + 1);
|
||||
tty->cursor.max.y = tty->cursor.max.y * 4;
|
||||
|
||||
// Try to alloc new tty output buffer
|
||||
tty->buffers.output = (char **)pm_alloc(sizeof(char *) * tty->cursor.max.y);
|
||||
if (tty->buffers.output == NULL)
|
||||
{
|
||||
pm_free(tty);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// Try to alloc each line of the output buffer
|
||||
line = tty->cursor.max.y;
|
||||
while (--line >= 0)
|
||||
{
|
||||
// Try to alloc the line
|
||||
tty->buffers.output[line] = (char*)pm_alloc(tty->cursor.max.x);
|
||||
if (tty->buffers.output[line] != NULL) {
|
||||
memset(tty->buffers.output[line], '\0', tty->cursor.max.x);
|
||||
continue;
|
||||
}
|
||||
// Release all allocated space and return NULL
|
||||
while (++line < tty->cursor.max.y)
|
||||
pm_free(tty->buffers.output[line]);
|
||||
pm_free(tty->buffers.output);
|
||||
pm_free(tty);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// Initialize default TTY cursor position.
|
||||
tty->cursor.x = 0;
|
||||
tty->cursor.y = 0;
|
||||
return (tty);
|
||||
}
|
||||
|
|
|
@ -2,11 +2,10 @@
|
|||
#include <kernel/drivers/keyboard.h>
|
||||
#include <kernel/drivers/timer.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <kernel/util/casio.h>
|
||||
#include <kernel/context.h>
|
||||
#include <kernel/syscall.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
// Intenral functions
|
||||
static int check_signal(struct keyboard_obj_s *keyboard, key_t key);
|
||||
|
@ -20,8 +19,8 @@ static void cursor_callback(struct keyboard_obj_s *keyboard);
|
|||
ssize_t tty_read(void *inode, void *buffer, size_t count)
|
||||
{
|
||||
extern struct keycache_s *keylist;
|
||||
struct keycache_s *keynode;
|
||||
struct keyboard_obj_s keyboard;
|
||||
struct keycache_s *keynode;
|
||||
int first_key;
|
||||
int timer_fd;
|
||||
|
||||
|
@ -29,8 +28,6 @@ ssize_t tty_read(void *inode, void *buffer, size_t count)
|
|||
if (count < 2)
|
||||
return (0);
|
||||
|
||||
// get tty device
|
||||
|
||||
// Initialize internal struc.
|
||||
memset(buffer, '\0', count);
|
||||
keyboard.buffer.addr = buffer;
|
||||
|
@ -305,6 +302,9 @@ static void cursor_callback(struct keyboard_obj_s *keyboard)
|
|||
// Draw cursor if needed
|
||||
if (keyboard->cvisible == 0)
|
||||
{
|
||||
// Force atomic operation
|
||||
atomic_start();
|
||||
|
||||
// Geneate TTY buffer cursor position.
|
||||
x = keyboard->buffer.cursor + keyboard->saved.tty.cursor.x;
|
||||
y = x / keyboard->tty->cursor.max.x;
|
||||
|
@ -318,19 +318,24 @@ static void cursor_callback(struct keyboard_obj_s *keyboard)
|
|||
keyboard->tty->cursor.x = x;
|
||||
keyboard->tty->cursor.y = y;
|
||||
|
||||
// Get Display X and Y position.
|
||||
// TODO: remove me / find better way !!
|
||||
tty_ioctl(keyboard->tty, TTY_IOCTL_GETDX, &x);
|
||||
tty_ioctl(keyboard->tty, TTY_IOCTL_GETDY, &y);
|
||||
// Get "real" X and Y position (pixel)
|
||||
x = x * (keyboard->tty->disp.font->font.width + 1);
|
||||
y = y * (keyboard->tty->disp.font->font.height + 1);
|
||||
|
||||
// Display cursor.
|
||||
kvram_reverse(x, y, (KERNEL_FONT_REAL_WIDTH + 1), (KERNEL_FONT_REAL_HEIGHT + 1));
|
||||
kvram_display();
|
||||
dreverse(
|
||||
&keyboard->tty->disp, x, y,
|
||||
(keyboard->tty->disp.font->font.width + 1),
|
||||
(keyboard->tty->disp.font->font.height + 1)
|
||||
);
|
||||
(*screen_update)(keyboard->tty->disp.vram);
|
||||
|
||||
// Restore TTY cursor position
|
||||
keyboard->tty->cursor.x = sttyx;
|
||||
keyboard->tty->cursor.y = sttyy;
|
||||
|
||||
// Stop atomic operations
|
||||
atomic_stop();
|
||||
}
|
||||
// Update cursor status.
|
||||
keyboard->cvisible = keyboard->cvisible ^ 1;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <kernel/devices/tty.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
/* tty_vertical_update() - Check / update TTY vertical cursor */
|
||||
static void tty_vertical_update(struct tty_s *tty)
|
||||
|
@ -13,7 +13,7 @@ static void tty_vertical_update(struct tty_s *tty)
|
|||
tty->cursor.y = 0;
|
||||
|
||||
// Wipe new line.
|
||||
memset(tty->buffer[tty->cursor.y], '\0', tty->cursor.max.x);
|
||||
memset(tty->buffers.output[tty->cursor.y], '\0', tty->cursor.max.x);
|
||||
}
|
||||
|
||||
/* tty_horizontal_update() - Check / update TTY horizotal cursor */
|
||||
|
@ -49,7 +49,7 @@ static ssize_t tty_buffer_update(struct tty_s *tty, const uint8_t *buffer, size_
|
|||
{
|
||||
if (tty->cursor.x > 0)
|
||||
tty->cursor.x = tty->cursor.x - 1;
|
||||
tty->buffer[tty->cursor.y][tty->cursor.x] = '\0';
|
||||
tty->buffers.output[tty->cursor.y][tty->cursor.x] = '\0';
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ static ssize_t tty_buffer_update(struct tty_s *tty, const uint8_t *buffer, size_
|
|||
offset = 5 - (tty->cursor.x - ((tty->cursor.x / 5) * 5));
|
||||
if (tty->cursor.x + offset < tty->cursor.max.x)
|
||||
{
|
||||
memset(&tty->buffer[tty->cursor.y][tty->cursor.x], ' ', offset);
|
||||
memset(&tty->buffers.output[tty->cursor.y][tty->cursor.x], ' ', offset);
|
||||
tty->cursor.x = tty->cursor.x + offset;
|
||||
continue;
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ static ssize_t tty_buffer_update(struct tty_s *tty, const uint8_t *buffer, size_
|
|||
if (buffer[i] == '\f' || buffer[i] == '\v')
|
||||
{
|
||||
tty_vertical_update(tty);
|
||||
memset(tty->buffer[tty->cursor.y], ' ', tty->cursor.x);
|
||||
memset(tty->buffers.output[tty->cursor.y], ' ', tty->cursor.x);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ static ssize_t tty_buffer_update(struct tty_s *tty, const uint8_t *buffer, size_
|
|||
if (buffer[i] == '\r') { tty->cursor.x = 0; continue;}
|
||||
|
||||
// Update TTY buffer char.
|
||||
tty->buffer[tty->cursor.y][tty->cursor.x] = buffer[i];
|
||||
tty->buffers.output[tty->cursor.y][tty->cursor.x] = buffer[i];
|
||||
tty_horizontal_update(tty);
|
||||
}
|
||||
return (i);
|
||||
|
@ -117,14 +117,14 @@ static void tty_display(struct tty_s *tty)
|
|||
// @note: circular buffer.
|
||||
line = 0;
|
||||
start = tty->cursor.y;
|
||||
while (++line < DISPLAY_VCHAR_MAX)
|
||||
while (++line < tty->cursor.max.y)
|
||||
{
|
||||
// Update check line.
|
||||
saved_start = start;
|
||||
start = (start - 1 < 0) ? tty->cursor.max.y : start - 1;
|
||||
start = (start - 1 < 0) ? tty->cursor.max.y - 1 : start - 1;
|
||||
|
||||
// Check if the line existe.
|
||||
if (tty->buffer[start][0] == '\0')
|
||||
if (tty->buffers.output[start][0] == '\0')
|
||||
{
|
||||
start = saved_start;
|
||||
break;
|
||||
|
@ -132,26 +132,23 @@ static void tty_display(struct tty_s *tty)
|
|||
}
|
||||
|
||||
// clear screen
|
||||
kvram_clear();
|
||||
dclear(&tty->disp);
|
||||
|
||||
// Display "on-screen" string lines.
|
||||
y = -1;
|
||||
while (++y < line)
|
||||
{
|
||||
// Get / check line lenght.
|
||||
line_len = strnlen(tty->buffer[start], tty->cursor.max.x);
|
||||
if (line_len == 0)
|
||||
continue;
|
||||
// Display line
|
||||
line_len = -1;
|
||||
while (tty->buffers.output[start][++line_len] != '\0')
|
||||
dascii(&tty->disp, line_len, y, tty->buffers.output[start][line_len]);
|
||||
|
||||
// Display line.
|
||||
kvram_print(0, y, tty->buffer[start], line_len);
|
||||
|
||||
// Get "next" line.
|
||||
start = (start + 1 > tty->cursor.max.y) ? 0 : start + 1;
|
||||
// Update row index
|
||||
start = (start + 1 < tty->cursor.max.y) ? start + 1 : 0;
|
||||
}
|
||||
|
||||
// Display on screen.
|
||||
kvram_display();
|
||||
(*screen_update)(tty->disp.vram);
|
||||
|
||||
// Stop atomic operation
|
||||
atomic_stop();
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#include <kernel/drivers/screen.h>
|
||||
|
||||
// Internal drivers
|
||||
extern void t6k11_variant_lcd_driver(void *vram);
|
||||
extern void t6k11_lcd_driver(void *vram);
|
||||
|
||||
// Primitives
|
||||
void (*screen_update)(void *vram);
|
||||
|
||||
__attribute__((constructor))
|
||||
static void screen_constructor(void)
|
||||
{
|
||||
// Check T6K11 variant which appear during
|
||||
// the OS >= 03.00.0000
|
||||
if (*(uint8_t*)0xa0010021 == '3') {
|
||||
screen_update = (void*)&t6k11_variant_lcd_driver;
|
||||
return;
|
||||
}
|
||||
// Default driver
|
||||
screen_update = &t6k11_lcd_driver;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#include <kernel/drivers/screen.h>
|
||||
|
||||
/* screen_get() - Internal screen getter */
|
||||
size_t screen_get(screen_getter_t getter)
|
||||
{
|
||||
switch (getter)
|
||||
{
|
||||
case SCREEN_WIDTH: return (128);
|
||||
case SCREEN_HEIGHT: return (64);
|
||||
}
|
||||
return (0);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
#include <kernel/util/debug.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
|
||||
void exception_handler(void)
|
||||
{
|
||||
|
@ -18,8 +18,8 @@ void exception_handler(void)
|
|||
);
|
||||
|
||||
// Write exception informations.
|
||||
kvram_clear();
|
||||
printk(0, 0,
|
||||
earlyterm_clear();
|
||||
earlyterm_write(
|
||||
"Ho crap ! Exception !\n"
|
||||
"tra: %#x\n"
|
||||
"expevt: %#x\n"
|
||||
|
@ -32,6 +32,5 @@ void exception_handler(void)
|
|||
ssr,
|
||||
sr
|
||||
);
|
||||
kvram_display();
|
||||
while (1);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <kernel/util/debug.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
|
||||
// Handler prototype.
|
||||
extern void keysc_handler(void);
|
||||
|
@ -24,13 +24,12 @@ void interrupt_handler(void)
|
|||
}
|
||||
|
||||
// Display error.
|
||||
kvram_clear();
|
||||
printk(0, 0,
|
||||
earlyterm_clear();
|
||||
earlyterm_write(
|
||||
"Ho crap ! Interrupt error !\n"
|
||||
"Interrupt ID (%#x)\n"
|
||||
"Error: handler not foud !\n",
|
||||
intevt
|
||||
);
|
||||
kvram_display();
|
||||
while (1);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <kernel/util/debug.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
|
||||
__attribute__((section(".vhex.tlb"), interrupt_handler))
|
||||
void tlb_handler(void)
|
||||
|
@ -19,8 +19,8 @@ void tlb_handler(void)
|
|||
);
|
||||
|
||||
// Write exception informations.
|
||||
kvram_clear();
|
||||
printk(0, 0,
|
||||
earlyterm_clear();
|
||||
earlyterm_write(
|
||||
"Ho crap ! TLB Exception !\n"
|
||||
"tra: %#x\n"
|
||||
"expevt: %#x\n"
|
||||
|
@ -33,6 +33,5 @@ void tlb_handler(void)
|
|||
ssr,
|
||||
sr
|
||||
);
|
||||
kvram_display();
|
||||
while (1);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <kernel/fs/gladfs.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
// Internal helper
|
||||
extern struct gladfs_fragment_data_s **gladfs_file_pos(off_t *offset, struct gladfs_inode_s *inode, off_t pos);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <kernel/fs/gladfs.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
// Internal helper
|
||||
extern struct gladfs_fragment_data_s **gladfs_file_pos(off_t *offset, struct gladfs_inode_s *inode, off_t pos);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <kernel/fs/gladfs.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
|
||||
/* gladfs_mount() - GladFS mount primitive (sync) */
|
||||
void *gladfs_mount(void)
|
||||
|
@ -18,9 +18,7 @@ void *gladfs_mount(void)
|
|||
gladfs_superblock.root_inode = gladfs_superblock.super_op.alloc_inode("/", GLADFS_INODE_TYPE_ROOT);
|
||||
if (gladfs_superblock.root_inode == NULL)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "GladFS: ROOT inode alloc error !");
|
||||
kvram_display();
|
||||
earlyterm_write("GladFS: ROOT inode alloc error !");
|
||||
DBG_WAIT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <kernel/fs/gladfs.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
/* gladfs_get_name() - Dump the name of a file (sync) */
|
||||
int gladfs_get_name(void *inode, char *name, size_t count)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <kernel/fs/gladfs.h>
|
||||
#include <kernel/memory.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
/* gladfs_alloc_inode() - Superblock primitive to alloc "empty" inode (sync) */
|
||||
struct gladfs_inode_s *gladfs_alloc_inode(const char *name, mode_t mode)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <kernel/fs/smemfs.h>
|
||||
#include <kernel/fs/file.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
/* casio_smem_data_base_address() - Generate the fragmented data address (0xa0000000 + offset) */
|
||||
static void *casio_smem_get_data_base_address(smemfs_fragdata_t *fragment)
|
||||
|
@ -17,7 +17,7 @@ static void *casio_smem_get_data_base_address(smemfs_fragdata_t *fragment)
|
|||
}
|
||||
if (block->info.id != fragment->data_block_id)
|
||||
return (NULL);
|
||||
return ((void *)(block->offset + fragment->data_offset));
|
||||
return ((void *)(uint32_t)(block->offset + fragment->data_offset));
|
||||
}
|
||||
|
||||
/* casio_smem_read() - Read the file data (based on internal cursor) */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <kernel/fs/smemfs.h>
|
||||
#include <kernel/fs/filesystem.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
|
||||
// Kernel FS block
|
||||
struct file_system_type smemfs_filesystem =
|
||||
|
@ -47,19 +47,20 @@ void smemfs_initialize(void)
|
|||
// Get / check Casio SMEM sector table
|
||||
// @note:
|
||||
// Casio SMEM sector table start
|
||||
// always at 0xa0270000.
|
||||
// always (?) at 0xa0270000 (tested with OS 1.00.0000).
|
||||
// TODO: return error !!
|
||||
smemfs_superblock.sector_table = (void *)0xa0270000;
|
||||
if (smemfs_superblock.sector_table->magic_start != 0x4200)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "SMEMFS: Casio sector table error !");
|
||||
printk(0, 1, "Wait manual reset...");
|
||||
kvram_display();
|
||||
earlyterm_clear();
|
||||
earlyterm_write("SMEMFS: Casio sector table error !");
|
||||
earlyterm_write("Wait manual reset...");
|
||||
while (1){ __asm__ volatile ("sleep"); }
|
||||
}
|
||||
|
||||
// Casio SMEM inode table start always at the end of the sector table.
|
||||
// Normaly start at 0xa0270320 but not always (?)
|
||||
// TODO: return error !!
|
||||
int i = -1;
|
||||
while (smemfs_superblock.sector_table[++i].magic_start == CASIO_SMEM_BLOCK_ENTRY_MAGIC);
|
||||
smemfs_superblock.inode_table = (void *)&smemfs_superblock.sector_table[i];
|
||||
|
@ -68,10 +69,9 @@ void smemfs_initialize(void)
|
|||
smemfs_superblock.inode_table->parent.id != 0xffff ||
|
||||
smemfs_superblock.inode_table->parent.type != 0xffff)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "SMEMFS: Casio inode table error !");
|
||||
printk(0, 1, "Wait manual reset...");
|
||||
kvram_display();
|
||||
earlyterm_clear();
|
||||
earlyterm_write("SMEMFS: Casio inode table error !");
|
||||
earlyterm_write("Wait manual reset...");
|
||||
while (1){ __asm__ volatile ("sleep"); }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,10 @@
|
|||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/process.h>
|
||||
#include <kernel/util/debug.h>
|
||||
|
||||
int sys_open(const char *pathname, int flags, ...)
|
||||
{
|
||||
extern struct process *process_current;
|
||||
|
||||
// DEBUG !
|
||||
/*kvram_clear();
|
||||
printk(0, 0, "Syscall open() !");
|
||||
printk(0, 1, "path: %s", pathname);
|
||||
printk(0, 2, "flags: %#x", flags);
|
||||
kvram_display();
|
||||
DBG_WAIT;*/
|
||||
|
||||
// Get current process
|
||||
if (process_current == NULL)
|
||||
return (-1);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/memory.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
/* vfs_dentry_alloc() - Allocate new "empty" dentry */
|
||||
struct dentry *vfs_dentry_alloc(const char *name, mode_t mode)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/fs/stat.h>
|
||||
#include <kernel/process.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
static int get_name(int *name_lenght, const char *path, char *name)
|
||||
{
|
||||
|
@ -39,9 +39,7 @@ struct dentry *vfs_dentry_resolve(const char *path, int mode)
|
|||
// Check VFS validity
|
||||
if (vfs_root_node == NULL)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "VFS root error !");
|
||||
kvram_display();
|
||||
earlyterm_write("VFS root error !");
|
||||
DBG_WAIT;
|
||||
return (NULL);
|
||||
}
|
||||
|
@ -107,13 +105,10 @@ struct dentry *vfs_dentry_resolve(const char *path, int mode)
|
|||
next = vfs_dentry_find_next_sibling(next);
|
||||
if (next == NULL)
|
||||
{
|
||||
// Debug !
|
||||
kvram_clear();
|
||||
printk(0, 0, "vfs_resolve(): sibling error !");
|
||||
printk(0, 1, "old next: %s$", tmp->name);
|
||||
printk(0, 2, "file: %s$", file->name);
|
||||
printk(0, 3, "name: %s$", name);
|
||||
kvram_display();
|
||||
earlyterm_write("vfs_resolve(): sibling error !");
|
||||
earlyterm_write("* old next: %s$", tmp->name);
|
||||
earlyterm_write("* file: %s$", file->name);
|
||||
earlyterm_write("* name: %s$", name);
|
||||
DBG_WAIT;
|
||||
return (NULL);
|
||||
}
|
||||
|
@ -129,26 +124,13 @@ struct dentry *vfs_dentry_resolve(const char *path, int mode)
|
|||
if ((file->mode & __S_IFDIR) == 0)
|
||||
{
|
||||
// Debug !
|
||||
kvram_clear();
|
||||
printk(0, 0, "vfs_resolve(): dir error !");
|
||||
kvram_display();
|
||||
earlyterm_write("vfs_resolve(): dir error !");
|
||||
DBG_WAIT;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// Try to find first child
|
||||
next = vfs_dentry_find_first_child(next);
|
||||
/*if (next != NULL)
|
||||
{
|
||||
// Debug !
|
||||
kvram_clear();
|
||||
printk(0, 0, "vfs_resolve(): child info !");
|
||||
printk(0, 1, "file name: %s$", file->name);
|
||||
printk(0, 2, "next name: %s$", next->name);
|
||||
printk(0, 3, "name: %s$", name);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
}*/
|
||||
|
||||
// Update name lenght to skip '/' char
|
||||
name_lenght = name_lenght + 1;
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/fs/stat.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
|
||||
/* vfs_open() - Open file named pathname */
|
||||
int vfs_open(FILE *file, char const *pathname, int flags)
|
||||
{
|
||||
struct dentry *dentry;
|
||||
|
||||
//TODO: handle flags !!
|
||||
(void)flags;
|
||||
|
||||
// Get target inode.
|
||||
dentry = vfs_dentry_resolve(pathname, 0);
|
||||
if (dentry == NULL)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "VFS_open() error !");
|
||||
printk(0, 1, "path error '%s'", pathname);
|
||||
kvram_display();
|
||||
earlyterm_write("VFS_open() error !");
|
||||
earlyterm_write("* path error '%s'", pathname);
|
||||
DBG_WAIT;
|
||||
return (-1);
|
||||
}
|
||||
|
@ -22,22 +23,20 @@ int vfs_open(FILE *file, char const *pathname, int flags)
|
|||
// Check directory.
|
||||
if ((dentry->mode & __S_IFDIR) != 0)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "VFS_open(): file type error '%s'", pathname);
|
||||
kvram_display();
|
||||
earlyterm_write("VFS_open(): file type error '%s'", pathname);
|
||||
DBG_WAIT;
|
||||
return (-2);
|
||||
}
|
||||
|
||||
//TODO: call FS specific open() primitive ?
|
||||
|
||||
// Debug
|
||||
kvram_clear();
|
||||
printk(0, 0, "vfs_open(): inode found !");
|
||||
printk(0, 1, "path: %s", pathname);
|
||||
printk(0, 2, "name: %s", dentry->name);
|
||||
printk(0, 3, "inode: %p", dentry->inode);
|
||||
printk(0, 4, "file_op: %p", dentry->dentry_op.file_op);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
/* earlyterm_write("vfs_open(): inode found !");
|
||||
earlyterm_write("* path: %s", pathname);
|
||||
earlyterm_write("* name: %s", dentry->name);
|
||||
earlyterm_write("* inode: %p", dentry->inode);
|
||||
earlyterm_write("* file_op: %p", dentry->dentry_op.file_op);
|
||||
DBG_WAIT;*/
|
||||
|
||||
// Update interne dentry counter
|
||||
dentry->counter = dentry->counter + 1;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
ssize_t vfs_read(FILE *file, void *buf, size_t count)
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/memory.h>
|
||||
#include <kernel/fs/stat.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
/* vfs_mkdir() - Attempts to create a directory named pathname */
|
||||
int vfs_mkdir(const char *pathname, mode_t mode)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/fs/stat.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
/* gevice_get() - Find internal device */
|
||||
struct device *device_get(dev_t major)
|
||||
|
@ -60,7 +60,6 @@ int vfs_mknod(const char *pathname, mode_t mode, dev_t dev)
|
|||
if (file->inode == NULL)
|
||||
return (-4);
|
||||
|
||||
|
||||
// Debug !
|
||||
/*kvram_clear();
|
||||
printk(0, 0, "New mknod device !");
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/memory.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <kernel/fs/stat.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
// Internal informations
|
||||
struct dentry *vfs_root_node = NULL;
|
||||
|
@ -31,6 +31,10 @@ int vfs_mount(const char *source, const char *target,
|
|||
const char *filesystemtype, unsigned long mountflags,
|
||||
const void *data)
|
||||
{
|
||||
// TODO: handle source and data !!
|
||||
(void)source;
|
||||
(void)data;
|
||||
|
||||
// Check error.
|
||||
if (filesystemtype == NULL)
|
||||
return (-1);
|
||||
|
@ -53,28 +57,19 @@ int vfs_mount(const char *source, const char *target,
|
|||
return (-1);
|
||||
|
||||
// Try to mount the FS.
|
||||
// TODO: add possibility to return to main menu
|
||||
vfs_root_node->inode = filesystem->filesystem_operations.mount();
|
||||
if (vfs_root_node->inode == NULL)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "VFS: Unable to mount ROOT inode !");
|
||||
printk(0, 1, "VFS: Wait manual reset...");
|
||||
kvram_display();
|
||||
earlyterm_clear();
|
||||
earlyterm_write("VFS: Unable to mount ROOT inode !");
|
||||
earlyterm_write("Wait manual reset...");
|
||||
while (1) { __asm__ volatile ("sleep"); }
|
||||
}
|
||||
|
||||
// Get File System primitives
|
||||
vfs_root_node->dentry_op.file_op = &filesystem->file_operations;
|
||||
vfs_root_node->dentry_op.inode_op = &filesystem->inode_operations;
|
||||
|
||||
// Debug !
|
||||
/*kvram_clear();
|
||||
printk(0, 0, "vfs_root_node = %p", vfs_root_node);
|
||||
printk(0, 1, "vfs_root_node = %s$", vfs_root_node->name);
|
||||
printk(0, 2, "vfs_root_node = %p", vfs_root_node->child);
|
||||
printk(0, 3, "vfs_root_node = %p", vfs_root_node->next);
|
||||
kvram_display();
|
||||
DBG_WAIT;*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,74 +1,43 @@
|
|||
#include <kernel/loader.h>
|
||||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/fs/file.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/util/elf.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
|
||||
void *loader(const char *path, struct process *process)
|
||||
//
|
||||
// TODO: write doc
|
||||
//
|
||||
int loader(struct process *process, const char *path)
|
||||
{
|
||||
Elf32_Ehdr header;
|
||||
FILE file;
|
||||
|
||||
// Check error.
|
||||
if (process == NULL)
|
||||
// Check error and try to open the file.
|
||||
if (process == NULL || vfs_open(&file, path, O_RDONLY) != 0)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "loader: Fault error !");
|
||||
printk(0, 1, "path: %s$", path);
|
||||
printk(0, 2, "process: %p", process);
|
||||
kvram_display();
|
||||
earlyterm_write("loader: Fault error !");
|
||||
earlyterm_write("* path: %s$", path);
|
||||
earlyterm_write("* process: %p", process);
|
||||
DBG_WAIT;
|
||||
return (NULL);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// TODO: use VFS !
|
||||
if (vfs_open(&file, path, O_RDONLY) != 0)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "loader: File open error !");
|
||||
printk(0, 1, "path: %s$", path);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// Debug !
|
||||
kvram_clear();
|
||||
printk(0, 0, "File found !!");
|
||||
printk(0, 1, "inode = %p", file.private);
|
||||
printk(0, 2, "path = %s", path);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
|
||||
//@NOTE: Only ELF supported !!!
|
||||
//TODO: USE VFS !!
|
||||
//
|
||||
// Get / Check ELF header
|
||||
// FIXME: return the file type (elf, g1a, bin, ...)
|
||||
if (loader_get_header(&file, &header) != 0)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "loader: ELF file header error !");
|
||||
kvram_display();
|
||||
earlyterm_write("loader: ELF file header error !");
|
||||
DBG_WAIT;
|
||||
return (NULL);
|
||||
return (-2);
|
||||
}
|
||||
|
||||
// Get / Check program validity
|
||||
void *entry = loader_load_image(&file, &header, process);
|
||||
if (entry == NULL)
|
||||
if (loader_load_image(process, &file, &header) != 0)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "loader: ELF file image error !");
|
||||
kvram_display();
|
||||
earlyterm_write("loader: ELF file image error !");
|
||||
DBG_WAIT;
|
||||
return (NULL);
|
||||
return (-3);
|
||||
}
|
||||
|
||||
// Success !
|
||||
kvram_clear();
|
||||
printk(0, 0, "loader: file loaded sucees !!");
|
||||
printk(0, 1, "loader: Entry at %p", entry);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
return (entry);
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include <kernel/loader.h>
|
||||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/memory.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
/* loader_load_image() - Load the program into Virtual Memory */
|
||||
void *loader_load_image(FILE *file, Elf32_Ehdr *header, struct process *process)
|
||||
int loader_load_image(struct process *process, FILE *file, Elf32_Ehdr *header)
|
||||
{
|
||||
Elf32_Phdr program;
|
||||
uint32_t paddress;
|
||||
|
@ -19,11 +19,11 @@ void *loader_load_image(FILE *file, Elf32_Ehdr *header, struct process *process)
|
|||
// Read programme header.
|
||||
vfs_lseek(file, header->e_phoff + (sizeof(Elf32_Phdr) * i), SEEK_SET);
|
||||
if (vfs_read(file, &program, sizeof(Elf32_Phdr)) != sizeof(Elf32_Phdr))
|
||||
return (NULL);
|
||||
return (-1);
|
||||
|
||||
// Check programe type.
|
||||
if (program.p_type != PT_LOAD)
|
||||
return (NULL);
|
||||
return (-2);
|
||||
|
||||
// Update program size
|
||||
process->memory.program.size = process->memory.program.size + program.p_memsz;
|
||||
|
@ -33,7 +33,7 @@ void *loader_load_image(FILE *file, Elf32_Ehdr *header, struct process *process)
|
|||
// physical memory.
|
||||
process->memory.program.start = (uint32_t)pm_alloc(process->memory.program.size);
|
||||
if (process->memory.program.start == 0x00000000)
|
||||
return (NULL);
|
||||
return (-3);
|
||||
|
||||
// Now, load all program section into
|
||||
// physical memory.
|
||||
|
@ -57,5 +57,6 @@ void *loader_load_image(FILE *file, Elf32_Ehdr *header, struct process *process)
|
|||
}
|
||||
|
||||
// Generate program entry address
|
||||
return ((void*)(header->e_entry + process->memory.program.start));
|
||||
process->context.spc = (uint32_t)(header->e_entry + (uint32_t)process->memory.program.start);
|
||||
return ((process->context.spc == 0x00000000));
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <kernel/memory.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
|
||||
void pm_free(void *ptr)
|
||||
{
|
||||
|
@ -17,12 +17,10 @@ void pm_free(void *ptr)
|
|||
// Check misaligned pointer.
|
||||
if (((uint32_t)ptr % PM_BLOCK_SIZE) != 0)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0,
|
||||
earlyterm_write(
|
||||
"pm_free: Warning, you try to free misaligned"
|
||||
"pointer address (%p)\n", sptr
|
||||
);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
return;
|
||||
}
|
||||
|
@ -49,11 +47,9 @@ void pm_free(void *ptr)
|
|||
}
|
||||
|
||||
// No block found, display error.
|
||||
kvram_clear();
|
||||
printk(0, 0,
|
||||
earlyterm_write(
|
||||
"pm_free: Warning, you try to free unused"
|
||||
"allocated memory (%p)", sptr
|
||||
);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <kernel/context.h>
|
||||
#include <kernel/hardware/tmu.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
|
||||
// Test
|
||||
uint32_t counter = 0;
|
||||
|
@ -24,14 +24,13 @@ void sched_debug(common_context_t *context_current, common_context_t *context_ne
|
|||
//SH7305_TMU.TIMER[1].TCR.UNF = 0;
|
||||
//SH7305_TMU.TIMER[2].TCR.UNF = 0;
|
||||
|
||||
kvram_clear();
|
||||
printk(0, 0, "Scheduler_schudele !");
|
||||
printk(0, 1, "context current = %p", context_current);
|
||||
printk(0, 2, "context next = %p", context_next);
|
||||
printk(0, 3, "counter = %#x", counter++);
|
||||
printk(0, 4, "TSTR: %#x", tstr);
|
||||
printk(0, 5, "TCOR: %#x", tcor);
|
||||
printk(0, 6, "TCNT: %#x", tcnt);
|
||||
printk(0, 7, "TCR: %#x", tcr);
|
||||
kvram_display();
|
||||
// Display internal data
|
||||
earlyterm_write("Scheduler_schudele !");
|
||||
earlyterm_write("context current = %p", context_current);
|
||||
earlyterm_write("context next = %p", context_next);
|
||||
earlyterm_write("counter = %#x", counter++);
|
||||
earlyterm_write("TSTR: %#x", tstr);
|
||||
earlyterm_write("TCOR: %#x", tcor);
|
||||
earlyterm_write("TCNT: %#x", tcnt);
|
||||
earlyterm_write("TCR: %#x", tcr);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include <kernel/process.h>
|
||||
#include <kernel/util/unistd_32.h>
|
||||
#include <kernel/memory.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/util/string.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
struct process *process_create(const char *name)
|
||||
{
|
||||
|
@ -19,9 +19,7 @@ struct process *process_create(const char *name)
|
|||
process_pid = process_alloc(&process);
|
||||
if (process == NULL)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "proc_error: alloc error !");
|
||||
kvram_display();
|
||||
earlyterm_write("proc_error: alloc error !");
|
||||
DBG_WAIT;
|
||||
return (NULL);
|
||||
}
|
||||
|
@ -31,9 +29,7 @@ struct process *process_create(const char *name)
|
|||
process->memory.stack.user = (uint32_t)pm_alloc(process->memory.stack.size.user);
|
||||
if (process->memory.stack.user == 0x00000000)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "proc_error: user stack error !");
|
||||
kvram_display();
|
||||
earlyterm_write("proc_error: user stack error !");
|
||||
DBG_WAIT;
|
||||
process_free(process);
|
||||
return (NULL);
|
||||
|
@ -45,9 +41,7 @@ struct process *process_create(const char *name)
|
|||
process->memory.stack.kernel = (uint32_t)pm_alloc(process->memory.stack.size.kernel);
|
||||
if (process->memory.stack.kernel == 0x00000000)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "proc_error: kernel stack error !");
|
||||
kvram_display();
|
||||
earlyterm_write("proc_error: kernel stack error !");
|
||||
DBG_WAIT;
|
||||
pm_free((void *)process->memory.stack.user);
|
||||
process_free(process);
|
||||
|
@ -56,12 +50,14 @@ struct process *process_create(const char *name)
|
|||
process->stack.kernel = process->memory.stack.kernel + process->memory.stack.size.kernel;
|
||||
|
||||
// initialize "exit" part.
|
||||
uint8_t callexit[6] = {
|
||||
// FIXME: add xor r4, r4
|
||||
uint8_t callexit[8] = {
|
||||
0b00100100, 0b01001010, // xor r4, r4
|
||||
0b11000011, __NR_exit, // trapa #__NR_exit
|
||||
0b10110000, 0b00000100, // bsr PC + 2 - 4
|
||||
0b00000000, 0b00001001 // nop
|
||||
};
|
||||
process->memory.exit.size = 6;
|
||||
process->memory.exit.size = 8;
|
||||
process->memory.exit.start = (uint32_t)(pm_alloc(process->memory.exit.size));
|
||||
if (process->memory.exit.start == 0x00000000)
|
||||
{
|
||||
|
@ -99,11 +95,9 @@ struct process *process_create(const char *name)
|
|||
process->working_dir = vfs_root_node;
|
||||
|
||||
// DEBUG !
|
||||
kvram_clear();
|
||||
printk(0, 0, "proc_create: success !");
|
||||
printk(0, 1, "user stack: %p", process->context.reg[15]);
|
||||
printk(0, 2, "kernel stack: %p", process->memory.stack.kernel);
|
||||
kvram_display();
|
||||
earlyterm_write("proc_create: success !\n");
|
||||
earlyterm_write("* user stack: %p\n", process->context.reg[15]);
|
||||
earlyterm_write("* kernel stack: %p\n", process->memory.stack.kernel);
|
||||
DBG_WAIT;
|
||||
|
||||
// Link new process with his parent.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <kernel/scheduler.h>
|
||||
#include <kernel/hardware/cpg.h>
|
||||
#include <kernel/hardware/tmu.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
#include <kernel/drivers/timer.h>
|
||||
|
||||
// Internal data used by the scheduler handler
|
||||
|
@ -28,13 +28,13 @@ uint32_t sched_timer_tstr_bit = 0;
|
|||
return;
|
||||
|
||||
// Debug
|
||||
//kvram_clear();
|
||||
//printk(0, 0, "Scheduler_schudele !");
|
||||
//printk(0, 1, "context current = %p", context_current);
|
||||
//printk(0, 2, "context next = %p", context_next);
|
||||
//kvram_display();
|
||||
//printk(0, 3, "context switch !");
|
||||
//kvram_display();
|
||||
//dclear(&kdisplay);
|
||||
//earlyterm_write(&kdisplay, 0, 0, "Scheduler_schudele !");
|
||||
//earlyterm_write(&kdisplay, 0, 1, "context current = %p", context_current);
|
||||
//earlyterm_write(&kdisplay, 0, 2, "context next = %p", context_next);
|
||||
//(*screen_update)(kdisplay.vram);
|
||||
//earlyterm_write(&kdisplay, 0, 3, "context switch !");
|
||||
//(*screen_update)(kdisplay.vram);
|
||||
//DBG_WAIT;
|
||||
|
||||
// Context switch
|
||||
|
@ -71,20 +71,18 @@ void sched_start(void)
|
|||
|
||||
|
||||
// Debug
|
||||
kvram_clear();
|
||||
printk(0, 0,
|
||||
"FLL freq: %d.%d Mhz\n"
|
||||
"PLL freq: %d.%d Mhz\n"
|
||||
"CPU freq: %d.%d Mhz\n"
|
||||
"BUS freq: %d.%d Mhz\n"
|
||||
"Per freq: %d.%d Mhz",
|
||||
earlyterm_write(
|
||||
"* FLL freq: %d.%d Mhz\n"
|
||||
"* PLL freq: %d.%d Mhz\n"
|
||||
"* CPU freq: %d.%d Mhz\n"
|
||||
"* BUS freq: %d.%d Mhz\n"
|
||||
"* Per freq: %d.%d Mhz\n",
|
||||
fll_freq / 1000000, (((fll_freq - ((fll_freq / 1000000)) * 1000000)) + 999) / 1000,
|
||||
pll_freq / 1000000, (((pll_freq - ((pll_freq / 1000000)) * 1000000)) + 999) / 1000,
|
||||
cpu_freq / 1000000, (((cpu_freq - ((cpu_freq / 1000000)) * 1000000)) + 999) / 1000,
|
||||
bus_freq / 1000000, (((bus_freq - ((bus_freq / 1000000)) * 1000000)) + 999) / 1000,
|
||||
per_freq / 1000000, (((per_freq - ((per_freq / 1000000)) * 1000000)) + 999) / 1000
|
||||
);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
|
||||
// Register first process !
|
||||
|
@ -100,12 +98,10 @@ void sched_start(void)
|
|||
sched_timer_tstr_bit = 1 << sched_timer_id;
|
||||
|
||||
// Debug
|
||||
kvram_clear();
|
||||
printk(0, 0, "timer ID: %d", sched_timer_id);
|
||||
printk(0, 1, "timer addr: %#x", sched_timer_address);
|
||||
printk(0, 2, "timer event: %#x", sched_timer_intevt);
|
||||
printk(0, 3, "timer TSTR: %#x", sched_timer_tstr_bit);
|
||||
kvram_display();
|
||||
earlyterm_write("* timer ID: %d\n", sched_timer_id);
|
||||
earlyterm_write("* timer addr: %#x\n", sched_timer_address);
|
||||
earlyterm_write("* timer event: %#x\n", sched_timer_intevt);
|
||||
earlyterm_write("* timer TSTR: %#x\n", sched_timer_tstr_bit);
|
||||
DBG_WAIT;
|
||||
|
||||
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
#include <kernel/scheduler.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
|
||||
void sys_exit(int status)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "PROCESS EXIT SYSCALL !!!!");
|
||||
printk(0, 0, "Wait manual reset...");
|
||||
kvram_display();
|
||||
// TODO handle status
|
||||
(void)status;
|
||||
|
||||
// Fow now, just wait manual reset...
|
||||
earlyterm_clear();
|
||||
earlyterm_write("PROCESS EXIT SYSCALL !!!!");
|
||||
earlyterm_write("Wait manual reset...");
|
||||
while (1);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <kernel/scheduler.h>
|
||||
#include <kernel/loader.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
|
||||
pid_t sys_fexecve(const char *pathname)
|
||||
{
|
||||
|
@ -17,21 +17,16 @@ pid_t sys_fexecve(const char *pathname)
|
|||
proc = process_create(pathname);
|
||||
if (proc == NULL)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "sys_fexecve: alloc error !");
|
||||
kvram_display();
|
||||
earlyterm_write("sys_fexecve: alloc error !");
|
||||
DBG_WAIT;
|
||||
atomic_stop();
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// Try to load binary into physical memory
|
||||
proc->context.spc = (uint32_t)loader(pathname, proc);
|
||||
if (proc->context.spc == 0x00000000)
|
||||
if (loader(proc, pathname) != 0)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "sys_fexecve: loader error !");
|
||||
kvram_display();
|
||||
earlyterm_write("sys_fexecve: loader error !");
|
||||
DBG_WAIT;
|
||||
process_free(proc);
|
||||
atomic_stop();
|
||||
|
@ -39,35 +34,26 @@ pid_t sys_fexecve(const char *pathname)
|
|||
}
|
||||
|
||||
// Debug
|
||||
kvram_clear();
|
||||
printk(0, 0, "New proc loaded !");
|
||||
kvram_display();
|
||||
earlyterm_write("New proc loaded !");
|
||||
DBG_WAIT;
|
||||
|
||||
// Add new process into task queue
|
||||
error = sched_add_task(proc);
|
||||
if (error != 0)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "sys_fexecve: scheduler error !");
|
||||
kvram_display();
|
||||
earlyterm_write("sys_fexecve: scheduler error !");
|
||||
DBG_WAIT;
|
||||
process_free(proc);
|
||||
atomic_stop();
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// Debug
|
||||
printk(0, 1, "New proc sched added !");
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
|
||||
// Get child process PID
|
||||
child_pid = process_get_pid(proc);
|
||||
|
||||
// Debug
|
||||
printk(0, 2, "New proc PID = %#x !", child_pid);
|
||||
kvram_display();
|
||||
earlyterm_write("New proc sched added !");
|
||||
earlyterm_write("New proc PID = %#x !", child_pid);
|
||||
DBG_WAIT;
|
||||
|
||||
// Stop atomic operations
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#include <kernel/syscall.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/devices/earlyterm.h>
|
||||
|
||||
static void sys_test(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "a = %#x", a);
|
||||
printk(0, 1, "b = %#x", b);
|
||||
printk(0, 2, "c = %#x", c);
|
||||
printk(0, 3, "d = %#x", d);
|
||||
kvram_display();
|
||||
earlyterm_clear();
|
||||
earlyterm_write("Syscall test entry:\n");
|
||||
earlyterm_write("* a = %#x\n", a);
|
||||
earlyterm_write("* b = %#x\n", b);
|
||||
earlyterm_write("* c = %#x\n", c);
|
||||
earlyterm_write("* d = %#x\n", d);
|
||||
DBG_WAIT;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/devices/tty.h>
|
||||
#include <kernel/memory.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/util/draw.h>
|
||||
#include <kernel/util/string.h>
|
||||
|
||||
// Tree-wrapper
|
||||
static void vfs_test(struct dentry *node, int level)
|
||||
{
|
||||
// Check error.
|
||||
if (node == NULL)
|
||||
return;
|
||||
|
||||
// Space management.
|
||||
for (int i = 0 ; i < level ; i++)
|
||||
tty_write(NULL, " ", 1);
|
||||
|
||||
// Display name
|
||||
tty_write(NULL, node->name, strlen(node->name));
|
||||
tty_write(NULL, "\n", 1);
|
||||
|
||||
// Walk into child and sibling
|
||||
vfs_test(vfs_dentry_find_first_child(node), level + 1);
|
||||
vfs_test(vfs_dentry_find_next_sibling(node), level);
|
||||
}
|
||||
|
||||
void kernel_test(void)
|
||||
{
|
||||
extern struct dentry *vfs_root_node;
|
||||
char path[] = "/../dev/./../dev/////tty";
|
||||
FILE file;
|
||||
|
||||
// Debug !
|
||||
kvram_clear();
|
||||
printk(0, 0, "Kernel test mode entry !");
|
||||
printk(0, 1, "Check VFS...");
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
|
||||
// Check root node
|
||||
printk(0, 2, "vfs_root_node = %p", vfs_root_node);
|
||||
printk(0, 3, "vfs_root_node = %s$", vfs_root_node->name);
|
||||
printk(0, 4, "vfs_root_node = %p", vfs_root_node->child);
|
||||
printk(0, 5, "vfs_root_node = %p", vfs_root_node->next);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
|
||||
// VFS test
|
||||
tty_open(0, 0);
|
||||
vfs_test(vfs_root_node, 0);
|
||||
tty_write(NULL, "FINI !\n", 7);
|
||||
DBG_WAIT;
|
||||
DBG_WAIT;
|
||||
|
||||
// Try to open file using VFS
|
||||
if (vfs_open(&file, path, 0))
|
||||
{
|
||||
kvram_clear();
|
||||
printk(0, 0, "vfs_open(): error !");
|
||||
printk(0, 1, "path %s$", path);
|
||||
kvram_display();
|
||||
while (1) { __asm__ volatile ("sleep"); }
|
||||
}
|
||||
|
||||
// Display file informations
|
||||
kvram_clear();
|
||||
printk(0, 0, "vfs_open: success !");
|
||||
printk(0, 1, "path: %s$", path);
|
||||
printk(0, 2, "file->private: %p", file.private);
|
||||
printk(0, 3, "file->file_op: %p", file.file_op);
|
||||
kvram_display();
|
||||
while (1);
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
#include <kernel/util/debug.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
void printk(int x, int y, char const *str, ...)
|
||||
{
|
||||
char hex[] = "0123456789abcdef";
|
||||
char buffer[16];
|
||||
int default_pos_x;
|
||||
int starting_x;
|
||||
int digits;
|
||||
int32_t nb;
|
||||
uint8_t base;
|
||||
va_list ap;
|
||||
int i;
|
||||
|
||||
// Get starting variable args
|
||||
va_start(ap, str);
|
||||
|
||||
// Initialize part
|
||||
i = -1;
|
||||
starting_x = x;
|
||||
x = x * (KERNEL_FONT_REAL_WIDTH + 1);
|
||||
y = y * (KERNEL_FONT_REAL_HEIGHT + 1);
|
||||
default_pos_x = x;
|
||||
|
||||
// Walk into string and display character by character
|
||||
while (str[++i] != '\0')
|
||||
{
|
||||
// New line
|
||||
if (str[i] == '\n')
|
||||
{
|
||||
y = y + KERNEL_FONT_REAL_HEIGHT + 1;
|
||||
x = default_pos_x;
|
||||
continue;
|
||||
}
|
||||
// Horizontal tab
|
||||
if (str[i] == '\t')
|
||||
{
|
||||
x = x / (KERNEL_FONT_REAL_WIDTH + 1);
|
||||
x = (x + (4 - ((x - starting_x) & 3))) * (KERNEL_FONT_REAL_WIDTH + 1);
|
||||
continue;
|
||||
}
|
||||
// String format "simple"
|
||||
if (str[i] == '%')
|
||||
{
|
||||
if (str[i + 1] == 'd' || str[i + 1] == 'x')
|
||||
{
|
||||
// Initialise
|
||||
digits = 0;
|
||||
nb = va_arg(ap, int32_t);
|
||||
base = (str[i + 1] == 'd') ? 10 : 16;
|
||||
|
||||
// Check negative value
|
||||
// FIXME: negative error (max)
|
||||
if (nb < 0 && str[i + 1] == 'd')
|
||||
{
|
||||
nb = 0 - nb;
|
||||
kvram_ascii(x, y, '-');
|
||||
x = x + KERNEL_FONT_REAL_WIDTH + 1;
|
||||
}
|
||||
|
||||
// Generate buffer
|
||||
// @note: generate in LSB mode.
|
||||
while (digits == 0 || nb != 0)
|
||||
{
|
||||
buffer[digits++] = hex[nb % base];
|
||||
nb = nb / base;
|
||||
}
|
||||
|
||||
// Reverse dans display string
|
||||
while (--digits >= 0)
|
||||
{
|
||||
kvram_ascii(x, y, buffer[digits]);
|
||||
x = x + KERNEL_FONT_REAL_WIDTH + 1;
|
||||
}
|
||||
i = i + 1;
|
||||
continue;
|
||||
}
|
||||
if ((str[i + 1] == '#' && str[i + 2] == 'x') || str[i + 1] == 'p')
|
||||
{
|
||||
// add @ if 'p' (pointer)
|
||||
if (str[i + 1] == 'p')
|
||||
{
|
||||
kvram_ascii(x, y, '@');
|
||||
x = x + KERNEL_FONT_REAL_WIDTH + 1;
|
||||
}
|
||||
|
||||
// Add "0x"
|
||||
kvram_ascii(x, y, '0');
|
||||
x = x + KERNEL_FONT_REAL_WIDTH + 1;
|
||||
kvram_ascii(x, y, 'x');
|
||||
x = x + KERNEL_FONT_REAL_WIDTH + 1;
|
||||
|
||||
// Get value
|
||||
digits = 0;
|
||||
nb = va_arg(ap, uint32_t);
|
||||
while (digits < 8)
|
||||
{
|
||||
buffer[digits++] = hex[nb & 0x0f];
|
||||
nb = nb >> 4;
|
||||
}
|
||||
|
||||
// Display string.
|
||||
while (--digits >= 0)
|
||||
{
|
||||
kvram_ascii(x, y, buffer[digits]);
|
||||
x = x + KERNEL_FONT_REAL_WIDTH + 1;
|
||||
}
|
||||
|
||||
// Update cursor
|
||||
i = (str[i + 1] == '#') ? i + 2 : i + 1;
|
||||
continue;
|
||||
}
|
||||
if (str[i + 1] == 's')
|
||||
{
|
||||
digits = 0;
|
||||
nb = va_arg(ap, uint32_t);
|
||||
while (((char*)nb)[digits] != '\0')
|
||||
{
|
||||
kvram_ascii(x, y, ((char*)nb)[digits++]);
|
||||
x = x + KERNEL_FONT_REAL_WIDTH + 1;
|
||||
}
|
||||
i = i + 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Default, display character
|
||||
kvram_ascii(x, y, str[i]);
|
||||
x = x + KERNEL_FONT_REAL_WIDTH + 1;
|
||||
}
|
||||
|
||||
// End of variodic args.
|
||||
va_end(ap);
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
#include <kernel/util/draw.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
|
||||
// Font bitmap.
|
||||
static const uint8_t kernel_font_bitmap[] = {
|
||||
0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
|
||||
0xee, 0xee, 0xee, 0xef, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
|
||||
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xad,
|
||||
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
|
||||
0x55, 0x55, 0x55, 0x5e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
|
||||
0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x2a, 0x92, 0x11, 0x11, 0x28, 0x00, 0x00, 0x38, 0xbb, 0xab, 0xbb, 0xbb,
|
||||
0x80, 0x08, 0x23, 0x02, 0x57, 0x31, 0x52, 0x41, 0x22, 0x00, 0x01, 0x51,
|
||||
0x11, 0x54, 0x41, 0x55, 0x22, 0x27, 0x21, 0x04, 0x0a, 0xc4, 0x40, 0x82,
|
||||
0xae, 0x0e, 0x04, 0xa2, 0xee, 0xee, 0xe2, 0xee, 0x00, 0x80, 0x24, 0x00,
|
||||
0x1c, 0xd1, 0x41, 0x04, 0x08, 0x80, 0x11, 0x45, 0x04, 0x45, 0x45, 0x44,
|
||||
0x88, 0x9c, 0x80, 0x10, 0x2b, 0x09, 0x81, 0x10, 0x02, 0x01, 0x03, 0x8b,
|
||||
0xb8, 0xbb, 0x8b, 0xb8, 0x20, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xee,
|
||||
0xec, 0xee, 0xea, 0xee, 0xa8, 0xae, 0xee, 0xee, 0x6e, 0xaa, 0xaa, 0xae,
|
||||
0xe0, 0xe4, 0x05, 0x55, 0x15, 0x11, 0x14, 0x89, 0x51, 0xd5, 0x55, 0x55,
|
||||
0x09, 0x55, 0x55, 0x45, 0x10, 0x54, 0x0b, 0xb2, 0x2b, 0xba, 0xb9, 0x13,
|
||||
0x22, 0xaa, 0xba, 0xb3, 0x92, 0xaa, 0x91, 0x12, 0x10, 0x80, 0x55, 0x54,
|
||||
0x54, 0x45, 0x52, 0x25, 0x45, 0x55, 0x47, 0x51, 0x25, 0x57, 0x52, 0x44,
|
||||
0x11, 0x00, 0xca, 0xee, 0xce, 0x8e, 0xae, 0xca, 0xea, 0xae, 0x8e, 0xac,
|
||||
0x4e, 0x4a, 0xa4, 0xee, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00,
|
||||
0x90, 0x9a, 0x11, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19,
|
||||
0x30, 0x39, 0x14, 0x31, 0x52, 0x54, 0x00, 0x42, 0x76, 0x26, 0x35, 0x37,
|
||||
0x55, 0x55, 0x57, 0x22, 0x20, 0x70, 0x6c, 0x86, 0xee, 0x6c, 0xc4, 0xa4,
|
||||
0xea, 0xaa, 0xac, 0xc4, 0xaa, 0xa4, 0xa4, 0x84, 0x26, 0xe1, 0x55, 0x15,
|
||||
0x08, 0x54, 0x89, 0x89, 0x55, 0x58, 0xd0, 0x49, 0x55, 0xd4, 0x90, 0x88,
|
||||
0x99, 0xc1, 0xb1, 0x99, 0x93, 0x2b, 0xb2, 0x9a, 0xa9, 0x20, 0xa3, 0x19,
|
||||
0x92, 0xa9, 0x39, 0x93, 0x03, 0x80
|
||||
};
|
||||
|
||||
static void font_draw_core(struct font_block_s *fblock)
|
||||
{
|
||||
extern uint32_t vram[256];
|
||||
uint8_t vram_offset_y;
|
||||
uint32_t pixel_cursor;
|
||||
uint8_t pixel_test;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
// Calculate VRAM buffer starting position.
|
||||
// @note:
|
||||
// The screen width size is always 128 and we
|
||||
// use 4-aligned Video RAM so 32 pixels per "slot"
|
||||
// and 128 / 32 = 4.
|
||||
// y * 4 can be optimised by used shift operator,
|
||||
// this is why we use y << 2 because 2^2 = 4.
|
||||
vram_offset_y = fblock->y << 2;
|
||||
|
||||
// Start atomic operations
|
||||
atomic_start();
|
||||
|
||||
// Draw character, pixer per pixel... (x_x)
|
||||
// TODO: update me !!
|
||||
y = -1;
|
||||
while (++y < fblock->height)
|
||||
{
|
||||
x = -1;
|
||||
while (++x < fblock->width)
|
||||
{
|
||||
// Get bitmap pixel test.
|
||||
pixel_cursor = fblock->bitmap.x + fblock->bitmap.y + x;
|
||||
pixel_test = 0x80 >> (pixel_cursor & 0x07);
|
||||
|
||||
// Check if the pixel is block or white.
|
||||
if (pixel_test & kernel_font_bitmap[pixel_cursor >> 3])
|
||||
{
|
||||
vram[((fblock->x + x) >> 5) + vram_offset_y] |=
|
||||
0x80000000 >> ((fblock->x + x) & 31);
|
||||
}
|
||||
}
|
||||
|
||||
// Update internal offset.
|
||||
fblock->bitmap.y = fblock->bitmap.y + KERNEL_FONT_BITMAP_WIDTH;
|
||||
vram_offset_y = vram_offset_y + 4;
|
||||
}
|
||||
|
||||
// Stop atomic operations
|
||||
atomic_stop();
|
||||
}
|
||||
|
||||
|
||||
/* kvram_ascii() - Draw ASCII character into Video RAM */
|
||||
void kvram_ascii(int x, int y, char const c)
|
||||
{
|
||||
struct font_block_s fblock;
|
||||
|
||||
// Check obvious error.
|
||||
if (x > DISPLAY_SCREEN_WIDTH || y > DISPLAY_SCREEN_HEIGHT)
|
||||
return;
|
||||
|
||||
// Calculate the charactere position (bitmap)
|
||||
fblock.bitmap.y = (c / KERNEL_FONT_NB_CHAR_X) * (KERNEL_FONT_BITMAP_WIDTH * KERNEL_FONT_BITMAP_CHEIGHT);
|
||||
fblock.bitmap.x = (c - ((c / KERNEL_FONT_NB_CHAR_X) * KERNEL_FONT_NB_CHAR_X)) * KERNEL_FONT_BITMAP_CWIDTH;
|
||||
|
||||
|
||||
// Check X axis culling
|
||||
// and get font "block" width.
|
||||
if (x < 0)
|
||||
{
|
||||
fblock.bitmap.x = fblock.bitmap.x + x;
|
||||
fblock.width = KERNEL_FONT_REAL_WIDTH + x;
|
||||
fblock.x = 0;
|
||||
} else {
|
||||
fblock.width =
|
||||
(x + KERNEL_FONT_REAL_WIDTH >= DISPLAY_SCREEN_WIDTH)
|
||||
? DISPLAY_SCREEN_WIDTH - x - 1
|
||||
: KERNEL_FONT_REAL_WIDTH;
|
||||
fblock.x = x;
|
||||
}
|
||||
|
||||
// Check Y axis culling.
|
||||
// and get font "block" height.
|
||||
if (y < 0)
|
||||
{
|
||||
fblock.height = KERNEL_FONT_REAL_HEIGHT + y;
|
||||
fblock.bitmap.y = fblock.bitmap.y + ((-y) * KERNEL_FONT_BITMAP_WIDTH);
|
||||
fblock.y = 0;
|
||||
} else {
|
||||
fblock.height =
|
||||
(y + KERNEL_FONT_REAL_HEIGHT >= DISPLAY_SCREEN_HEIGHT)
|
||||
? DISPLAY_SCREEN_HEIGHT - y - 1
|
||||
: KERNEL_FONT_REAL_HEIGHT;
|
||||
fblock.y = y;
|
||||
}
|
||||
|
||||
// Check useless draw.
|
||||
if (fblock.width < 0 || fblock.height < 0)
|
||||
return;
|
||||
|
||||
// Draw ASCII character.
|
||||
font_draw_core(&fblock);
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
#include <kernel/util/draw.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
|
||||
// Internal Video RAM
|
||||
uint32_t vram[256];
|
||||
|
||||
/* kvram_clear() - Wipe the Video RAM */
|
||||
void kvram_clear(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
// The Video RAM is shared between each
|
||||
// process and the kernel, so we should
|
||||
// use atomic operation when we use it.
|
||||
atomic_start();
|
||||
|
||||
// Wipe Video RAM
|
||||
// @note: here, we suppose that the VRAM is
|
||||
// 4-aligned
|
||||
i = 256;
|
||||
while (--i >= 0)
|
||||
vram[i] = 0x00000000;
|
||||
|
||||
// End of atomic operation
|
||||
atomic_stop();
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
//#include <kernel/util/draw.h>
|
||||
//#include <kernel/devices/display.h>
|
||||
//#include <kernel/atomic.h>
|
||||
|
||||
/* kvram_clr_str_area() - Clear area based on kernel font size on Video RAM */
|
||||
//FIXME: secure (DO NOT USE IT !!!!!!)
|
||||
/*void kvram_clr_str_area(int x, int y, int width, int height)
|
||||
{
|
||||
uint32_t vram_offset_y;
|
||||
int cur_x;
|
||||
int cur_y;
|
||||
|
||||
// Initialize part
|
||||
x = x * (KERNEL_FONT_REAL_WIDTH + 1);
|
||||
y = y * (KERNEL_FONT_REAL_HEIGHT + 1);
|
||||
width = width * (KERNEL_FONT_REAL_WIDTH + 1);
|
||||
height = height * (KERNEL_FONT_REAL_HEIGHT + 1);
|
||||
|
||||
// Get VRAM offset
|
||||
vram_offset_y = y << 2;
|
||||
|
||||
// Start atomic operations
|
||||
atomic_start();
|
||||
|
||||
// Clear area, pixel per pixel x____x
|
||||
// TODO: update me !!!!
|
||||
cur_y = -1;
|
||||
while (++cur_y < height)
|
||||
{
|
||||
cur_x = -1;
|
||||
while (++cur_x < width)
|
||||
{
|
||||
vram[((x + cur_x) >> 5) + vram_offset_y] &=
|
||||
~(0x80000000 >> ((x + cur_x) & 31));
|
||||
}
|
||||
|
||||
// update internal counter
|
||||
vram_offset_y = vram_offset_y + 4;
|
||||
}
|
||||
|
||||
// Stop atomic operations
|
||||
atomic_stop();
|
||||
}*/
|
|
@ -1,16 +0,0 @@
|
|||
#include <kernel/util/draw.h>
|
||||
|
||||
/* kvram_display() - Disaplay Video RAM into screen */
|
||||
void kvram_display(void)
|
||||
{
|
||||
extern void t6k11_variant_lcd_driver(void *vram);
|
||||
extern void t6k11_lcd_driver(void *vram);
|
||||
extern uint32_t vram[256];
|
||||
|
||||
//TODO: handle screen hadware !
|
||||
//TODO: load dynamically screen driver during the boot
|
||||
if (*(uint8_t*)0xa0010021 == '3')
|
||||
t6k11_variant_lcd_driver((void*)vram);
|
||||
else
|
||||
t6k11_lcd_driver(vram);
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#include <kernel/util/draw.h>
|
||||
|
||||
void kvram_print(int x, int y, char const *string, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
// Generate pixel positions
|
||||
x = x * (KERNEL_FONT_REAL_WIDTH + 1);
|
||||
y = y * (KERNEL_FONT_REAL_HEIGHT + 1);
|
||||
|
||||
i = -1;
|
||||
while (++i < len)
|
||||
{
|
||||
// display ASCII char
|
||||
kvram_ascii(x, y, string[i]);
|
||||
|
||||
// Update X position.
|
||||
x = x + KERNEL_FONT_REAL_WIDTH + 1;
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
#include <kernel/util/draw.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
|
||||
/* kvram_scroll() - Scroll up the Video RAM */
|
||||
//FIXME: This part is hardware specific (128x64px)!!
|
||||
void kvram_scroll(int lines)
|
||||
{
|
||||
extern uint32_t vram[256];
|
||||
int i;
|
||||
|
||||
// The Video RAM is shared between each
|
||||
// process and the kernel, so we should
|
||||
// use atomic operation when we use it.
|
||||
atomic_start();
|
||||
|
||||
// Scoll n lines
|
||||
i = 0;
|
||||
while ((i >> 2) < 63 - lines)
|
||||
{
|
||||
vram[i + 0] = vram[i + (lines << 2) + 0];
|
||||
vram[i + 1] = vram[i + (lines << 2) + 1];
|
||||
vram[i + 2] = vram[i + (lines << 2) + 2];
|
||||
vram[i + 3] = vram[i + (lines << 2) + 3];
|
||||
i = i + 4;
|
||||
}
|
||||
// Clear last n lines
|
||||
while ((i >> 2) < 64)
|
||||
{
|
||||
vram[i + 0] = 0x00000000;
|
||||
vram[i + 1] = 0x00000000;
|
||||
vram[i + 2] = 0x00000000;
|
||||
vram[i + 3] = 0x00000000;
|
||||
i = i + 4;
|
||||
}
|
||||
|
||||
// End of atomic operation
|
||||
atomic_stop();
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
#include <kernel/util/string.h>
|
||||
|
||||
//TODO: update me !!
|
||||
void *memcpy(void *dest, const void *src, size_t count)
|
||||
{
|
||||
for (size_t i = 0 ; i < count ; i = i + 1)
|
||||
((uint8_t*)dest)[i] = ((uint8_t*)src)[i];
|
||||
return (dest);
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
#include <kernel/util/string.h>
|
||||
|
||||
//TODO: update me :(
|
||||
void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
while ((int)--n >= 0)
|
||||
((uint8_t*)s)[n] = c;
|
||||
return (s);
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
#include <kernel/util/string.h>
|
||||
|
||||
char *strcat(char *dest, char const *src)
|
||||
{
|
||||
size_t i;
|
||||
size_t start;
|
||||
|
||||
if (src == NULL || dest == NULL)
|
||||
return (0);
|
||||
i = -1;
|
||||
start = -1;
|
||||
while (dest[++start] != '\0');
|
||||
while (src[++i] != '\0')
|
||||
dest[start + i] = src[i];
|
||||
dest[i + start] = '\0';
|
||||
return (dest);
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
#include <kernel/util/string.h>
|
||||
|
||||
//TODO: asm ?
|
||||
char *strchr(const char *s1, int c)
|
||||
{
|
||||
int i = -1;
|
||||
while (s1[++i] != '\0' && s1[i] != c);
|
||||
return ((s1[i] == '\0') ? NULL : (void*)&s1[i]);
|
||||
}
|
||||
|
||||
//TODO: asm ?
|
||||
char *strchrnul(const char *s1, int c)
|
||||
{
|
||||
int i = -1;
|
||||
while (s1[++i] != '\0' && s1[i] != c);
|
||||
return ((void*)&s1[i]);
|
||||
}
|
||||
|
||||
//TODO asm ?
|
||||
char *strrchr(const char *s1, int c)
|
||||
{
|
||||
void *saved;
|
||||
|
||||
saved = NULL;
|
||||
for (int i = 0 ; s1[i] != '\0' ; i++)
|
||||
{
|
||||
if (s1[i] == c)
|
||||
saved = (void *)&s1[i];
|
||||
}
|
||||
return (saved);
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
#include <kernel/util/string.h>
|
||||
|
||||
int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
if (s1 == NULL || s2 == NULL)
|
||||
return (0);
|
||||
while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
|
||||
{
|
||||
s1 += 1;
|
||||
s2 += 1;
|
||||
}
|
||||
return (*s1 - *s2);
|
||||
}
|
||||
|
||||
int strncmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
if (s1 == NULL || s2 == NULL || n == 0)
|
||||
return (0);
|
||||
size_t i = -1;
|
||||
while (++i < n - 1 && s1[i] != '\0' && s2[i] != '\0' && s1[i] == s2[i]);
|
||||
return (s1[i] - s2[i]);
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
#include <kernel/util/string.h>
|
||||
|
||||
char *strcpy(char *dest, char const *src)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (src == NULL || dest == NULL)
|
||||
return (0);
|
||||
i = -1;
|
||||
while (src[++i] != '\0')
|
||||
dest[i] = src[i];
|
||||
dest[i] = '\0';
|
||||
return (dest);
|
||||
}
|
||||
|
||||
char *strncpy(char *dest, char const *str, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (str == NULL || dest == NULL)
|
||||
return (0);
|
||||
i = -1;
|
||||
while (++i < size && str[i] != '\0')
|
||||
dest[i] = str[i];
|
||||
dest[i] = '\0';
|
||||
return (dest);
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
#include <kernel/util/string.h>
|
||||
|
||||
size_t strlen(char const *str)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (str == NULL)
|
||||
return (0);
|
||||
i = -1;
|
||||
while (str[++i] != '\0');
|
||||
return (i);
|
||||
}
|
||||
|
||||
size_t strnlen(char const *str, size_t maxlen)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (str == NULL)
|
||||
return (0);
|
||||
i = -1;
|
||||
while (str[++i] != '\0' && (size_t)i < maxlen);
|
||||
return (i);
|
||||
}
|
|
@ -28,7 +28,7 @@ $(foreach mod,$(TARGET-MODULES),$(eval \
|
|||
target-$(mod)-obj := $$(subst /,_,$$(basename $$(target-$(mod)-src))) $n\
|
||||
target-$(mod)-obj := $$(patsubst %,$(BUILD)%.o,$$(target-$(mod)-obj)) $n\
|
||||
))
|
||||
TARGET-LIBS := $(patsubst %,lib_%.a,$(TARGET-MODULES))
|
||||
TARGET-LIBS := $(patsubst %,lib%.a,$(TARGET-MODULES))
|
||||
|
||||
|
||||
|
||||
|
@ -36,7 +36,7 @@ TARGET-LIBS := $(patsubst %,lib_%.a,$(TARGET-MODULES))
|
|||
#------- --------#
|
||||
# Generic rules #
|
||||
#------- --------#
|
||||
all: | $(BUILD) $(TARGET-LIBS)
|
||||
all: $(TARGET-LIBS)
|
||||
|
||||
$(BUILD):
|
||||
@ printf "Create $(blue)$@$(nocolor) directory\n"
|
||||
|
@ -56,13 +56,13 @@ debug:
|
|||
# Rule functions #
|
||||
#------- --------#
|
||||
define rule-src
|
||||
$(patsubst %,$(BUILD)%.o,$(subst /,_,$(basename $1))): $1
|
||||
$(patsubst %,$(BUILD)%.o,$(subst /,_,$(basename $1))): $1 | $(BUILD)
|
||||
@ printf "compiling $(white)$$<$(nocolor)..."
|
||||
@ $(CC) $(CFLAGS) -c $$< -o $$@ $(HEADER)
|
||||
@ printf "$(green)[ok]$(nocolor)\n"
|
||||
endef
|
||||
define rule-link
|
||||
$(patsubst %,lib_%.a,$1): $2
|
||||
$(patsubst %,lib%.a,$1): $2
|
||||
@ printf "Link $(green)$$@$(nocolor) lib\n"
|
||||
$(AR) crs $$@ $$^
|
||||
endef
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
#include <kernel/util/unistd_32.h>
|
||||
.text
|
||||
.global _dascii
|
||||
.type _dascii, @function
|
||||
|
||||
|
||||
.align 2
|
||||
_dascii:
|
||||
trapa #__NR_kvram_ascii
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -0,0 +1,99 @@
|
|||
#include <lib/display.h>
|
||||
#include <kernel/drivers/screen.h>
|
||||
|
||||
static void font_draw_core(uint32_t *vram, struct font_s *font, struct font_block_s *fblock)
|
||||
{
|
||||
uint8_t vram_offset_y;
|
||||
uint32_t pixel_cursor;
|
||||
uint8_t pixel_test;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
// Calculate VRAM buffer starting position.
|
||||
// @note:
|
||||
// The screen width size is always 128 and we
|
||||
// use 4-aligned Video RAM so 32 pixels per "slot"
|
||||
// and 128 / 32 = 4.
|
||||
// y * 4 can be optimised by used shift operator,
|
||||
// this is why we use y << 2 because 2^2 = 4.
|
||||
vram_offset_y = fblock->y << 2;
|
||||
|
||||
// Draw character, pixer per pixel... (x_x)
|
||||
// TODO: update me !!
|
||||
y = -1;
|
||||
while (++y < fblock->height)
|
||||
{
|
||||
x = -1;
|
||||
while (++x < fblock->width)
|
||||
{
|
||||
// Get bitmap pixel test.
|
||||
pixel_cursor = fblock->bitmap.x + fblock->bitmap.y + x;
|
||||
pixel_test = 0x80 >> (pixel_cursor & 0x07);
|
||||
|
||||
// Check if the pixel is block or white.
|
||||
if (pixel_test & font->bitmap.raw[pixel_cursor >> 3])
|
||||
{
|
||||
vram[((fblock->x + x) >> 5) + vram_offset_y] |=
|
||||
0x80000000 >> ((fblock->x + x) & 31);
|
||||
}
|
||||
}
|
||||
|
||||
// Update internal offset.
|
||||
fblock->bitmap.y = fblock->bitmap.y + font->bitmap.width;
|
||||
vram_offset_y = vram_offset_y + 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* dascii() - Draw ASCII character into Video RAM */
|
||||
void dascii(display_t *disp, int x, int y, char const c)
|
||||
{
|
||||
struct font_block_s fblock;
|
||||
|
||||
// Check obvious error.
|
||||
if (x > (int)disp->display.width || y > (int)disp->display.height)
|
||||
return;
|
||||
|
||||
// Calculate the charactere position (bitmap)
|
||||
fblock.bitmap.y = (c / disp->nb_char_width) * (disp->font->bitmap.width * disp->font->bitmap.cheight);
|
||||
fblock.bitmap.x = (c - ((c / disp->nb_char_width) * disp->nb_char_width)) * disp->font->bitmap.cwidth;
|
||||
|
||||
// Calculate real pixel position
|
||||
x = x * (disp->font->font.width + 1);
|
||||
y = y * (disp->font->font.height + 1);
|
||||
|
||||
// Check X axis culling
|
||||
// and get font "block" width.
|
||||
if (x < 0)
|
||||
{
|
||||
fblock.bitmap.x = fblock.bitmap.x + x;
|
||||
fblock.width = disp->font->font.width + x;
|
||||
fblock.x = 0;
|
||||
} else {
|
||||
fblock.width = disp->font->font.width;
|
||||
if (x + (int)disp->font->font.width >= (int)disp->display.width)
|
||||
fblock.width = disp->display.width - x - 1;
|
||||
fblock.x = x;
|
||||
}
|
||||
|
||||
// Check Y axis culling.
|
||||
// and get font "block" height.
|
||||
if (y < 0)
|
||||
{
|
||||
fblock.height = disp->font->font.height + y;
|
||||
fblock.bitmap.y = fblock.bitmap.y + ((-y) * disp->font->bitmap.width);
|
||||
fblock.y = 0;
|
||||
} else {
|
||||
fblock.height = disp->font->font.height;
|
||||
if (y + (int)disp->font->font.height >= (int)disp->display.height)
|
||||
fblock.height = disp->display.height - y - 1;
|
||||
fblock.y = y;
|
||||
}
|
||||
|
||||
// Check useless draw.
|
||||
if (fblock.width < 0 || fblock.height < 0)
|
||||
return;
|
||||
|
||||
// Draw ASCII character.
|
||||
font_draw_core(disp->vram, disp->font, &fblock);
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
#include <kernel/util/unistd_32.h>
|
||||
.text
|
||||
.global _dclear
|
||||
.type _dclear, @function
|
||||
|
||||
|
||||
.align 2
|
||||
_dclear:
|
||||
trapa #__NR_kvram_clear
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -0,0 +1,15 @@
|
|||
#include <lib/display.h>
|
||||
|
||||
/* dclear() - Wipe the Video RAM */
|
||||
void dclear(display_t *disp)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Wipe Video RAM
|
||||
// @note: here, we suppose that the VRAM
|
||||
// is 4-aligned.
|
||||
i = 256;
|
||||
while (--i >= 0)
|
||||
disp->vram[i] = 0x00000000;
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
#include <kernel/util/unistd_32.h>
|
||||
.text
|
||||
.global _dclr_str_area
|
||||
.type _dclr_str_area, @function
|
||||
|
||||
|
||||
.align 2
|
||||
_dclr_str_area:
|
||||
trapa #__NR_kvram_clr_str_area
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -0,0 +1,19 @@
|
|||
#include <lib/display.h>
|
||||
|
||||
int dopen(display_t *disp, const char *fontname)
|
||||
{
|
||||
extern struct font_s default5x3;
|
||||
|
||||
// TODO: handle font name
|
||||
(void)fontname;
|
||||
disp->font = &default5x3;
|
||||
|
||||
// Display size is hardcoded for now
|
||||
disp->display.width = 128;
|
||||
disp->display.height = 64;
|
||||
|
||||
// Pre-calculate internal value used to draw
|
||||
disp->nb_char_width = disp->font->bitmap.width + disp->font->bitmap.cwidth - 1;
|
||||
disp->nb_char_width = disp->nb_char_width / disp->font->bitmap.cwidth;
|
||||
return (0);
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
#include "kernel/util/unistd_32.h"
|
||||
.text
|
||||
.global _dprint
|
||||
.type _dprint, @function
|
||||
|
||||
|
||||
.align 2
|
||||
_dprint:
|
||||
trapa #__NR_kvram_print
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -0,0 +1,237 @@
|
|||
#include <lib/display.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
// Structure used to store
|
||||
// internal data
|
||||
struct dintern_s
|
||||
{
|
||||
display_t *disp;
|
||||
size_t counter;
|
||||
va_list ap;
|
||||
int x;
|
||||
int y;
|
||||
int force;
|
||||
};
|
||||
|
||||
// Internal functions
|
||||
static void disp_char(struct dintern_s *intern, char n);
|
||||
static void dchar(struct dintern_s *intern, char spec);
|
||||
static void dstr(struct dintern_s *intern, char spec);
|
||||
static void duint(struct dintern_s *intern, char spec);
|
||||
static void dint(struct dintern_s *intern, char spec);
|
||||
static void dptr(struct dintern_s *intern, char spec);
|
||||
|
||||
|
||||
// Internal actions list
|
||||
void (*actions_list[26])(struct dintern_s *intern, char spec) = {
|
||||
NULL, NULL, dchar, dint,
|
||||
NULL, NULL, NULL, NULL,
|
||||
dint, NULL, NULL, NULL,
|
||||
NULL, NULL, duint, dptr,
|
||||
NULL, NULL, dstr, NULL,
|
||||
duint, NULL, NULL, duint,
|
||||
NULL, NULL,
|
||||
};
|
||||
|
||||
|
||||
/* dchar() - display only one char */
|
||||
static void dchar(struct dintern_s *intern, char spec)
|
||||
{
|
||||
(void)spec;
|
||||
disp_char(intern, (char)va_arg(intern->ap, int));
|
||||
}
|
||||
|
||||
/* dstr() - display string */
|
||||
static void dstr(struct dintern_s *intern, char spec)
|
||||
{
|
||||
char *str;
|
||||
|
||||
(void)spec;
|
||||
str = va_arg(intern->ap, char *);
|
||||
while (*str != '\0')
|
||||
{
|
||||
disp_char(intern, *str);
|
||||
str = str + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* dint() - Display unsigned interger */
|
||||
static void duint(struct dintern_s *intern, char spec)
|
||||
{
|
||||
const char hexa[] = "0123456789abcdef";
|
||||
char buffer[32];
|
||||
uint32_t num;
|
||||
int digits;
|
||||
int base;
|
||||
|
||||
// Get appropriate base
|
||||
base = (spec == 'x') ? 16 : 10;
|
||||
|
||||
// TODO: handle size
|
||||
num = va_arg(intern->ap, uint32_t);
|
||||
|
||||
// Generate number (reverse)
|
||||
digits = 0;
|
||||
while (num != 0 || digits == 0) {
|
||||
buffer[digits++] = hexa[num % base];
|
||||
num = num / base;
|
||||
}
|
||||
while (--digits >= 0) {
|
||||
disp_char(intern, buffer[digits]);
|
||||
}
|
||||
}
|
||||
|
||||
/* dptr() - Display pointer address */
|
||||
static void dptr(struct dintern_s *intern, char spec)
|
||||
{
|
||||
const char hexa[] = "0123456789abcdef";
|
||||
char buffer[32];
|
||||
uint32_t num;
|
||||
int digits;
|
||||
|
||||
// Avoid unused parameter error
|
||||
(void)spec;
|
||||
|
||||
// Display default string
|
||||
disp_char(intern, '@');
|
||||
disp_char(intern, '0');
|
||||
disp_char(intern, 'x');
|
||||
|
||||
// TODO: handle size
|
||||
num = va_arg(intern->ap, uint32_t);
|
||||
|
||||
// Generate number (reverse)
|
||||
digits = 0;
|
||||
while (num != 0 || digits < 8) {
|
||||
buffer[digits++] = hexa[num & 15];
|
||||
num = num >> 4;
|
||||
}
|
||||
while (--digits >= 0) {
|
||||
disp_char(intern, buffer[digits]);
|
||||
}
|
||||
}
|
||||
|
||||
/* dint() - Display signed number (base 10) */
|
||||
static void dint(struct dintern_s *intern, char spec)
|
||||
{
|
||||
char buffer[32];
|
||||
int32_t num;
|
||||
int digits;
|
||||
|
||||
// Avoid unused parameters
|
||||
(void)spec;
|
||||
|
||||
// TODO: handle size
|
||||
num = va_arg(intern->ap, int32_t);
|
||||
|
||||
// Check negative value
|
||||
// FIXME: maximum negative value !!!!!!
|
||||
if (num < 0) {
|
||||
disp_char(intern, '-');
|
||||
num = -num;
|
||||
}
|
||||
|
||||
// Generate number (reverse)
|
||||
digits = 0;
|
||||
while (num != 0 || digits == 0) {
|
||||
buffer[digits++] = (num % 10) + '0';
|
||||
num = num / 10;
|
||||
}
|
||||
while (--digits >= 0) {
|
||||
disp_char(intern, buffer[digits]);
|
||||
}
|
||||
}
|
||||
|
||||
/* line_discipline() - small line discipline */
|
||||
static int line_discipline(struct dintern_s *intern, char n)
|
||||
{
|
||||
// New line
|
||||
if (n == '\n')
|
||||
{
|
||||
intern->y = intern->y + intern->disp->font->font.height + 1;
|
||||
intern->x = 0;
|
||||
return (0);
|
||||
}
|
||||
// Horizontal tab
|
||||
if (n == '\t')
|
||||
{
|
||||
intern->x = intern->x / (intern->disp->font->font.width + 1);
|
||||
intern->x = (intern->x + (4 - (intern->x & 3)));
|
||||
intern->x = intern->x * (intern->disp->font->font.width + 1);
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
|
||||
}
|
||||
|
||||
/* disp_char() - display on character and update internal data */
|
||||
static void disp_char(struct dintern_s *intern, char n)
|
||||
{
|
||||
dascii(intern->disp, intern->x, intern->y, n);
|
||||
intern->x = intern->x + (intern->disp->font->font.width + 1);
|
||||
intern->counter = intern->counter + 1;
|
||||
intern->force = intern->force - 1;
|
||||
}
|
||||
|
||||
/* dprint() - printf wrapper */
|
||||
size_t dprint(display_t *disp, int x, int y, const char *format, ...)
|
||||
{
|
||||
void (*action)(struct dintern_s *intern, char spec);
|
||||
struct dintern_s intern;
|
||||
void *sformat;
|
||||
|
||||
// Get variable args entry
|
||||
va_start(intern.ap, format);
|
||||
|
||||
// Generate pixel positions
|
||||
intern.x = x * (disp->font->font.width + 1);
|
||||
intern.y = y * (disp->font->font.height + 1);
|
||||
|
||||
// Initialise internal data
|
||||
intern.counter = 0;
|
||||
intern.force = 0;
|
||||
|
||||
// Display string char by char...
|
||||
format = format - 1;
|
||||
while (*(++format) != '\0')
|
||||
{
|
||||
// Check line discipline character
|
||||
if (line_discipline(&intern, *format) != 0)
|
||||
continue;
|
||||
|
||||
// Check general character or forced character
|
||||
if (*format != '%' || intern.force > 0) {
|
||||
disp_char(&intern, *format);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check "%%" format
|
||||
if (format[1] == '%') {
|
||||
disp_char(&intern, '%');
|
||||
format = format + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get format options
|
||||
// TODO: get options
|
||||
sformat = (void *)format;
|
||||
if (!(*format >= 'A' && *format <= 'Z') &&
|
||||
!(*format >= 'a' && *format <= 'z')) {
|
||||
intern.force = (uint32_t)format - (uint32_t)sformat;
|
||||
format = sformat;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get action if possible
|
||||
action = actions_list[(*format | 0x20) - 'a'];
|
||||
if (action == NULL) {
|
||||
intern.force = (uint32_t)format - (uint32_t)sformat;
|
||||
format = sformat;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Call actions
|
||||
(*action)(&intern, *format);
|
||||
}
|
||||
return (intern.counter);
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
#include <kernel/util/unistd_32.h>
|
||||
.text
|
||||
.global _dreverse
|
||||
.type _dreverse, @function
|
||||
|
||||
|
||||
.align 2
|
||||
_dreverse:
|
||||
trapa #__NR_kvram_reverse
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,10 +1,8 @@
|
|||
#include <kernel/util/draw.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <lib/display.h>
|
||||
|
||||
/* kvram_reverse() - Reverse Video RAM area */
|
||||
void kvram_reverse(int x, int y, int width, int height)
|
||||
/* dreverse() - Reverse Video RAM area */
|
||||
void dreverse(display_t *disp, int x, int y, int width, int height)
|
||||
{
|
||||
extern uint32_t vram[256];
|
||||
int vram_offset_y;
|
||||
int j;
|
||||
|
||||
|
@ -18,8 +16,8 @@ void kvram_reverse(int x, int y, int width, int height)
|
|||
width = width + x;
|
||||
x = 0;
|
||||
} else {
|
||||
if (x + width >= DISPLAY_SCREEN_WIDTH)
|
||||
width = DISPLAY_SCREEN_WIDTH - x;
|
||||
if (x + width >= (int)disp->display.width)
|
||||
width = disp->display.width - x;
|
||||
}
|
||||
|
||||
// Get "real" Y position and area height.
|
||||
|
@ -28,8 +26,8 @@ void kvram_reverse(int x, int y, int width, int height)
|
|||
height = height + x;
|
||||
y = 0;
|
||||
} else {
|
||||
if (y + height >= DISPLAY_SCREEN_HEIGHT)
|
||||
height = DISPLAY_SCREEN_HEIGHT - x;
|
||||
if (y + height >= (int)disp->display.height)
|
||||
height = disp->display.height - x;
|
||||
}
|
||||
|
||||
// Check potential error.
|
||||
|
@ -47,23 +45,14 @@ void kvram_reverse(int x, int y, int width, int height)
|
|||
// this is why we use y << 2 because 2^2 = 4.
|
||||
vram_offset_y = (y + height - 1) << 2;
|
||||
|
||||
|
||||
// The Video RAM is sheared between each
|
||||
// process and the kernel, so we should
|
||||
// use atomic operation when we use it.
|
||||
atomic_start();
|
||||
|
||||
// Reverse area
|
||||
while (--height >= 0)
|
||||
{
|
||||
j = width + x;
|
||||
while (--j >= x)
|
||||
{
|
||||
vram[(j >> 5) + vram_offset_y] ^= 0x80000000 >> (j & 31);
|
||||
disp->vram[(j >> 5) + vram_offset_y] ^= 0x80000000 >> (j & 31);
|
||||
}
|
||||
vram_offset_y = vram_offset_y - 4;
|
||||
}
|
||||
|
||||
// End of atomic operation
|
||||
atomic_stop();
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
#include <kernel/util/unistd_32.h>
|
||||
.text
|
||||
.global _dscroll
|
||||
.type _dscroll, @function
|
||||
|
||||
|
||||
.align 2
|
||||
_dclear:
|
||||
trapa #__NR_kvram_scroll
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -0,0 +1,28 @@
|
|||
#include <lib/display.h>
|
||||
|
||||
/* dscroll() - Scroll up the Video RAM */
|
||||
//FIXME: This part is hardware specific (128x64px)!!
|
||||
void dscroll(display_t *disp, int lines)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Scoll n lines
|
||||
i = 0;
|
||||
while ((i >> 2) < 63 - lines)
|
||||
{
|
||||
disp->vram[i + 0] = disp->vram[i + (lines << 2) + 0];
|
||||
disp->vram[i + 1] = disp->vram[i + (lines << 2) + 1];
|
||||
disp->vram[i + 2] = disp->vram[i + (lines << 2) + 2];
|
||||
disp->vram[i + 3] = disp->vram[i + (lines << 2) + 3];
|
||||
i = i + 4;
|
||||
}
|
||||
// Clear last n lines
|
||||
while ((i >> 2) < 64)
|
||||
{
|
||||
disp->vram[i + 0] = 0x00000000;
|
||||
disp->vram[i + 1] = 0x00000000;
|
||||
disp->vram[i + 2] = 0x00000000;
|
||||
disp->vram[i + 3] = 0x00000000;
|
||||
i = i + 4;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
#include <lib/display.h>
|
||||
|
||||
// Define the (hardcoded) font bitmap informations.
|
||||
#define DEFAULT_FONT_BITMAP_WIDTH (127) // Bitmap width
|
||||
#define DEFAULT_FONT_BITMAP_HEIGHT (23) // Bitmap height
|
||||
#define DEFAULT_FONT_BITMAP_CWIDTH (4) // Character width (bitmap)
|
||||
#define DEFAULT_FONT_BITMAP_CHEIGHT (6) // Character height (bitmap)
|
||||
#define DEFAULT_FONT_REAL_WIDTH (3) // Charater width (real)
|
||||
#define DEFAULT_FONT_REAL_HEIGHT (5) // Character height (real)
|
||||
|
||||
// Font bitmap (raw).
|
||||
static const uint8_t default_font_bitmap[] = {
|
||||
0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
|
||||
0xee, 0xee, 0xee, 0xef, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
|
||||
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x56, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xad,
|
||||
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
|
||||
0x55, 0x55, 0x55, 0x5e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
|
||||
0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x2a, 0x92, 0x11, 0x11, 0x28, 0x00, 0x00, 0x38, 0xbb, 0xab, 0xbb, 0xbb,
|
||||
0x80, 0x08, 0x23, 0x02, 0x57, 0x31, 0x52, 0x41, 0x22, 0x00, 0x01, 0x51,
|
||||
0x11, 0x54, 0x41, 0x55, 0x22, 0x27, 0x21, 0x04, 0x0a, 0xc4, 0x40, 0x82,
|
||||
0xae, 0x0e, 0x04, 0xa2, 0xee, 0xee, 0xe2, 0xee, 0x00, 0x80, 0x24, 0x00,
|
||||
0x1c, 0xd1, 0x41, 0x04, 0x08, 0x80, 0x11, 0x45, 0x04, 0x45, 0x45, 0x44,
|
||||
0x88, 0x9c, 0x80, 0x10, 0x2b, 0x09, 0x81, 0x10, 0x02, 0x01, 0x03, 0x8b,
|
||||
0xb8, 0xbb, 0x8b, 0xb8, 0x20, 0x82, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xee,
|
||||
0xec, 0xee, 0xea, 0xee, 0xa8, 0xae, 0xee, 0xee, 0x6e, 0xaa, 0xaa, 0xae,
|
||||
0xe0, 0xe4, 0x05, 0x55, 0x15, 0x11, 0x14, 0x89, 0x51, 0xd5, 0x55, 0x55,
|
||||
0x09, 0x55, 0x55, 0x45, 0x10, 0x54, 0x0b, 0xb2, 0x2b, 0xba, 0xb9, 0x13,
|
||||
0x22, 0xaa, 0xba, 0xb3, 0x92, 0xaa, 0x91, 0x12, 0x10, 0x80, 0x55, 0x54,
|
||||
0x54, 0x45, 0x52, 0x25, 0x45, 0x55, 0x47, 0x51, 0x25, 0x57, 0x52, 0x44,
|
||||
0x11, 0x00, 0xca, 0xee, 0xce, 0x8e, 0xae, 0xca, 0xea, 0xae, 0x8e, 0xac,
|
||||
0x4e, 0x4a, 0xa4, 0xee, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00,
|
||||
0x90, 0x9a, 0x11, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19,
|
||||
0x30, 0x39, 0x14, 0x31, 0x52, 0x54, 0x00, 0x42, 0x76, 0x26, 0x35, 0x37,
|
||||
0x55, 0x55, 0x57, 0x22, 0x20, 0x70, 0x6c, 0x86, 0xee, 0x6c, 0xc4, 0xa4,
|
||||
0xea, 0xaa, 0xac, 0xc4, 0xaa, 0xa4, 0xa4, 0x84, 0x26, 0xe1, 0x55, 0x15,
|
||||
0x08, 0x54, 0x89, 0x89, 0x55, 0x58, 0xd0, 0x49, 0x55, 0xd4, 0x90, 0x88,
|
||||
0x99, 0xc1, 0xb1, 0x99, 0x93, 0x2b, 0xb2, 0x9a, 0xa9, 0x20, 0xa3, 0x19,
|
||||
0x92, 0xa9, 0x39, 0x93, 0x03, 0x80
|
||||
};
|
||||
|
||||
// Internal global font object
|
||||
struct font_s default5x3 = {
|
||||
.bitmap = {
|
||||
.width = DEFAULT_FONT_BITMAP_WIDTH,
|
||||
.height = DEFAULT_FONT_BITMAP_HEIGHT,
|
||||
.cwidth = DEFAULT_FONT_BITMAP_CWIDTH,
|
||||
.cheight = DEFAULT_FONT_BITMAP_CHEIGHT,
|
||||
.raw = (void*)default_font_bitmap
|
||||
},
|
||||
.font = {
|
||||
.width = DEFAULT_FONT_REAL_WIDTH,
|
||||
.height = DEFAULT_FONT_REAL_HEIGHT
|
||||
}
|
||||
};
|
|
@ -11,3 +11,12 @@ int strcmp(const char *s1, const char *s2)
|
|||
}
|
||||
return (*s1 - *s2);
|
||||
}
|
||||
|
||||
int strncmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
if (s1 == NULL || s2 == NULL || n == 0)
|
||||
return (0);
|
||||
size_t i = -1;
|
||||
while (++i < n - 1 && s1[i] != '\0' && s2[i] != '\0' && s1[i] == s2[i]);
|
||||
return (s1[i] - s2[i]);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ include ../../../global.mk
|
|||
## Static variables
|
||||
##--
|
||||
HEADER := -I../../../include -I../../../include/user
|
||||
LIBS := -L../../lib/ -l_unistd -l_stdio -l_string -l_display
|
||||
BUILD := ../../../build/user/shell
|
||||
DEBUG := ../../../debug_bin
|
||||
OUTPUT := ../../../output
|
||||
|
@ -18,6 +17,7 @@ NAME := shell
|
|||
EXEC := $(OUTPUT)/$(NAME).elf
|
||||
LDFLAG := -T $(NAME).ld
|
||||
MEMORY_MAP := $(DEBUG)/$(NAME).map
|
||||
LIBS := -L../../lib -lstring -ldisplay -lunistd -lgcc
|
||||
|
||||
|
||||
|
||||
|
@ -42,10 +42,10 @@ OBJ := $(patsubst ._%,$(BUILD)/%.o,$(subst /,_,$(subst src/,,$(basename $(SRC)))
|
|||
##---
|
||||
## General rules
|
||||
##---
|
||||
all: | $(BUILD) $(DEBUG) $(EXEC)
|
||||
all: $(EXEC)
|
||||
|
||||
$(EXEC): $(OBJ)
|
||||
$(CC) -fPIC -Wl,-M $(LDFLAG) $(CFLAGS) -o $(DEBUG)/$(NAME).elf.big $(OBJ) $(HEADER) $(LIBS) -lgcc > $(MEMORY_MAP)
|
||||
$(EXEC): $(OBJ) | $(DEBUG)
|
||||
$(CC) -fPIC -Wl,-M $(LDFLAG) $(CFLAGS) -o $(DEBUG)/$(NAME).elf.big $(OBJ) $(HEADER) $(LIBS) > $(MEMORY_MAP)
|
||||
$(OBJCOPY) -S $(DEBUG)/$(NAME).elf.big $@
|
||||
rm -f $(DEBUG)/$(NAME).elf.big
|
||||
|
||||
|
@ -75,7 +75,7 @@ sec:
|
|||
## Automated rules
|
||||
##---
|
||||
define rule-src
|
||||
$(patsubst ._%,$(BUILD)/%.o,$(subst /,_,$(subst src/,,$(basename $1)))): $1
|
||||
$(patsubst ._%,$(BUILD)/%.o,$(subst /,_,$(subst src/,,$(basename $1)))): $1 | $(BUILD)
|
||||
@ printf "compiling $(white)$$<$(nocolor)..."
|
||||
@ $(CC) -fPIC $(CFLAGS) -o $$@ -c $$< $(HEADER) -lgcc
|
||||
@ printf "$(green)[ok]$(nocolor)\n"
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
|
||||
int builtin_proc(void)
|
||||
{
|
||||
pid_t child;
|
||||
// pid_t child;
|
||||
|
||||
// Debug
|
||||
dclear();
|
||||
dprint(0, 0, "Proc builtin !");
|
||||
dupdate();
|
||||
// dclear();
|
||||
// dprint(0, 0, "Proc builtin !");
|
||||
// dupdate();
|
||||
for (int i = 0 ; i < 3000000 ; i++);
|
||||
|
||||
// Try to create first child
|
||||
|
|
|
@ -11,8 +11,8 @@ int main(void)
|
|||
{
|
||||
char input[12];
|
||||
int cmd_size;
|
||||
char **argv;
|
||||
int argc;
|
||||
//char **argv;
|
||||
//int argc;
|
||||
int fd;
|
||||
|
||||
// Try to open TTY
|
||||
|
@ -24,10 +24,12 @@ int main(void)
|
|||
if (fd < 0)
|
||||
{
|
||||
// Display error.
|
||||
dclear();
|
||||
dprint(0, 0, "User program fail to open TTY");
|
||||
dprint(0, 1, "Wait user manual reset...");
|
||||
dupdate();
|
||||
display_t disp;
|
||||
dopen(&disp, "default");
|
||||
dclear(&disp);
|
||||
dprint(&disp, 0, 0, "User program fail to open TTY");
|
||||
dprint(&disp, 0, 1, "Wait user manual reset...");
|
||||
dupdate(&disp);
|
||||
|
||||
// Wait user manual reset.
|
||||
while (1)
|
||||
|
|
|
@ -23,7 +23,7 @@ int check_builtin(char *cmd)
|
|||
{
|
||||
|
||||
// Process test
|
||||
dclear();
|
||||
/* dclear();
|
||||
dprint(0, 0, "Process Load Test !");
|
||||
|
||||
// Load process test
|
||||
|
@ -52,7 +52,7 @@ int check_builtin(char *cmd)
|
|||
//int wstatus;
|
||||
//pid_t pid;
|
||||
//int i;
|
||||
|
||||
*/
|
||||
// Try to find builtin
|
||||
/* for (int i = 0 ; i < 1 ; i++)
|
||||
{
|
||||
|
@ -85,4 +85,4 @@ int check_builtin(char *cmd)
|
|||
// }
|
||||
// }
|
||||
// return (1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ include ../../../global.mk
|
|||
## Static variables
|
||||
##--
|
||||
HEADER := -I../../../include -I../../../include/user
|
||||
LIBS := -L../../lib/ -l_unistd -l_stdio -l_string -l_display
|
||||
LIBS := -L../../lib/ -lunistd -lstdio -lstring -ldisplay -lgcc
|
||||
BUILD := ../../../build/user/test
|
||||
DEBUG := ../../../debug_bin
|
||||
OUTPUT := ../../../output
|
||||
|
@ -45,7 +45,7 @@ OBJ := $(patsubst ._%,$(BUILD)/%.o,$(subst /,_,$(subst src/,,$(basename $(SRC)))
|
|||
all: | $(BUILD) $(DEBUG) $(EXEC)
|
||||
|
||||
$(EXEC): $(OBJ)
|
||||
$(CC) -fPIC -Wl,-M $(LDFLAG) $(CFLAGS) -o $(DEBUG)/$(NAME).elf.big $(OBJ) $(HEADER) $(LIBS) -lgcc > $(MEMORY_MAP)
|
||||
$(CC) -fPIC -Wl,-M $(LDFLAG) $(CFLAGS) -o $(DEBUG)/$(NAME).elf.big $(OBJ) $(HEADER) $(LIBS) > $(MEMORY_MAP)
|
||||
$(OBJCOPY) -S $(DEBUG)/$(NAME).elf.big $@
|
||||
rm -f $(DEBUG)/$(NAME).elf.big
|
||||
|
||||
|
|
Loading…
Reference in New Issue