Update project organisation (part 1)
This commit is contained in:
parent
6576cf1e5d
commit
4be64372bb
|
@ -1,40 +0,0 @@
|
|||
#ifndef __KERNEL_DEVICES_DISPLAY_H__
|
||||
# define __KERNEL_DEVICES_DISPLAY_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <kernel/util/types.h>
|
||||
#include <kernel/util/draw.h>
|
||||
|
||||
// Define screen informations.
|
||||
#define DISPLAY_SCREEN_WIDTH (128)
|
||||
#define DISPLAY_SCREEN_HEIGHT (64)
|
||||
|
||||
// Define Number of vertical lines
|
||||
// and horizontal lines.
|
||||
#define DISPLAY_VCHAR_MAX (DISPLAY_SCREEN_HEIGHT / (KERNEL_FONT_REAL_HEIGHT + 1))
|
||||
#define DISPLAY_HCHAR_MAX (DISPLAY_SCREEN_WIDTH / (KERNEL_FONT_REAL_WIDTH + 1))
|
||||
|
||||
// Device primitives.
|
||||
extern int display_open(void);
|
||||
extern ssize_t display_write(const void *buffer, size_t count);
|
||||
extern int display_close(void);
|
||||
|
||||
// IOCTL code.
|
||||
#define DISPLAY_IOCTL_GETX (0x00)
|
||||
#define DISPLAY_IOCTL_GETY (0x01)
|
||||
#define DISPLAY_IOCTL_SETX (0x02)
|
||||
#define DISPLAY_IOCTL_SETY (0x03)
|
||||
#define DISPLAY_IOCTL_CLEAR (0x04)
|
||||
#define DISPLAY_IOCTL_DISPLAY (0x05)
|
||||
extern void display_ioctl(uint32_t cmd, ...);
|
||||
|
||||
|
||||
// Sheared Video RAM
|
||||
// @note:
|
||||
// The user *SHOULD* not use the
|
||||
// VRAM without atomic operation (because
|
||||
// of reentrance).
|
||||
extern uint32_t vram[256];
|
||||
|
||||
#endif /*__KERNEL_DEVICES_DISPLAY_H__*/
|
|
@ -26,14 +26,16 @@ struct tty_s
|
|||
int16_t y;
|
||||
} max;
|
||||
} cursor;
|
||||
struct {
|
||||
|
||||
/*struct {
|
||||
ssize_t (*write)(const void *buffer, size_t count);
|
||||
ssize_t (*read)(void *buffer, size_t count);
|
||||
} primitives;
|
||||
} primitives;*/
|
||||
};
|
||||
|
||||
// internal strct used by the TTY read primitives
|
||||
// TODO: Move me ?
|
||||
// TODO: Add internal keyboard buffer !!!
|
||||
struct keyboard_obj_s
|
||||
{
|
||||
struct {
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
#ifndef __KERNEL_DEVICES_UBC_H__
|
||||
# define __KERNEL_DEVICES_UBC_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct ubc_context_s
|
||||
{
|
||||
uint32_t reg[16];
|
||||
uint32_t gbr;
|
||||
uint32_t macl;
|
||||
uint32_t mach;
|
||||
uint32_t ssr;
|
||||
uint32_t spc;
|
||||
};
|
||||
|
||||
typedef struct ubc_session_s
|
||||
{
|
||||
struct {
|
||||
struct {
|
||||
uint32_t cursor;
|
||||
} context;
|
||||
struct {
|
||||
int32_t vcursor;
|
||||
int32_t hcursor;
|
||||
} disassembly;
|
||||
} menu;
|
||||
struct ubc_context_s *context;
|
||||
unsigned int key;
|
||||
int channel;
|
||||
} ubc_session_t;
|
||||
|
||||
// Primitives.
|
||||
extern int ubc_open(void);
|
||||
extern int ubc_close(void);
|
||||
|
||||
#endif /*__KERNEL_DEVICES_UBC_H__*/
|
|
@ -14,6 +14,17 @@
|
|||
#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 screen informations.
|
||||
#define DISPLAY_SCREEN_WIDTH (128)
|
||||
#define DISPLAY_SCREEN_HEIGHT (64)
|
||||
|
||||
// Define Number of vertical lines
|
||||
// and horizontal lines.
|
||||
#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
|
||||
|
@ -36,6 +47,7 @@ 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,10 +0,0 @@
|
|||
#include <kernel/devices/keyboard.h>
|
||||
|
||||
// Internal constructor.
|
||||
extern void keycache_init(void);
|
||||
|
||||
int keyboard_open(void)
|
||||
{
|
||||
keycache_init();
|
||||
return (0);
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#include <kernel/devices/keyboard.h>
|
||||
|
||||
ssize_t keyboard_read(void *buffer, size_t count)
|
||||
{
|
||||
extern struct keycache_s *keylist;
|
||||
extern volatile uint8_t keylist_isUpdate;
|
||||
|
||||
// Wait key list update.
|
||||
while (keylist_isUpdate == 0)
|
||||
{
|
||||
__asm__ volatile ("sleep");
|
||||
}
|
||||
return (0);
|
||||
}
|
|
@ -1,189 +0,0 @@
|
|||
#include <kernel/devices/tty.h>
|
||||
#include <kernel/devices/display.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/util/string.h>
|
||||
|
||||
// Internal TTY object.
|
||||
extern struct tty_s tty;
|
||||
|
||||
static void tty_vertical_update(void)
|
||||
{
|
||||
// Get next line.
|
||||
tty.cursor.y =
|
||||
(tty.cursor.y + 1 <= tty.cursor.max.y)
|
||||
? tty.cursor.y + 1
|
||||
: 0;
|
||||
|
||||
// Wipe new line.
|
||||
memset(tty.buffer[tty.cursor.y], '\0', tty.cursor.max.x);
|
||||
}
|
||||
|
||||
static int tty_horizontal_update(void)
|
||||
{
|
||||
tty.cursor.x = tty.cursor.x + 1;
|
||||
if (tty.cursor.x >= tty.cursor.max.x)
|
||||
{
|
||||
tty_vertical_update();
|
||||
tty.cursor.x = 0;
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
// Line discipline :D
|
||||
static ssize_t tty_buffer_update(const uint8_t *buffer, size_t count)
|
||||
{
|
||||
int16_t offset;
|
||||
ssize_t i;
|
||||
|
||||
i = -1;
|
||||
while (++i < (ssize_t)count)
|
||||
{
|
||||
// Check bell char.
|
||||
if (buffer[i] == '\a')
|
||||
{
|
||||
// TODO
|
||||
continue;
|
||||
}
|
||||
// Check backspace.
|
||||
if (buffer[i] == '\b')
|
||||
{
|
||||
if (tty.cursor.x > 0)
|
||||
tty.cursor.x = tty.cursor.x - 1;
|
||||
tty.buffer[tty.cursor.y][tty.cursor.x] = '\0';
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check horizotal tab.
|
||||
if (buffer[i] == '\t')
|
||||
{
|
||||
// Check if we need a new line or not.
|
||||
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);
|
||||
tty.cursor.x = tty.cursor.x + offset;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If a new line is required char.
|
||||
// Generate a new line.
|
||||
tty.cursor.x = 0;
|
||||
tty_vertical_update();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check new line char.
|
||||
if (buffer[i] == '\n')
|
||||
{
|
||||
tty.cursor.x = 0;
|
||||
tty_vertical_update();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Check 'form feed' and 'vertical tab' char.
|
||||
// @note: for now this character is interpreted like '\v'
|
||||
if (buffer[i] == '\f' || buffer[i] == '\v')
|
||||
{
|
||||
tty_vertical_update();
|
||||
memset(tty.buffer[tty.cursor.y], ' ', tty.cursor.x);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check carriage return.
|
||||
if (buffer[i] == '\r') { tty.cursor.x = 0; continue;}
|
||||
|
||||
// Update TTY buffer char.
|
||||
tty.buffer[tty.cursor.y][tty.cursor.x] = buffer[i];
|
||||
tty_horizontal_update();
|
||||
}
|
||||
return (i);
|
||||
}
|
||||
|
||||
// FIXME: this function is device-specific !
|
||||
// TODO: Update me ?
|
||||
static void tty_display(void)
|
||||
{
|
||||
int saved_start;
|
||||
int line_len;
|
||||
int scolumn;
|
||||
int srow;
|
||||
int line;
|
||||
int start;
|
||||
int i;
|
||||
|
||||
// Start atomic operation.
|
||||
atomic_start();
|
||||
|
||||
// Save display "context".
|
||||
display_ioctl(DISPLAY_IOCTL_GETY, &srow);
|
||||
display_ioctl(DISPLAY_IOCTL_GETX, &scolumn);
|
||||
|
||||
// Clear Display
|
||||
// TODO: IOCTL to disable auto put on screen.
|
||||
display_ioctl(DISPLAY_IOCTL_CLEAR);
|
||||
|
||||
// Get the "first" line and number of line.
|
||||
// @note: circular buffer.
|
||||
line = 0;
|
||||
start = tty.cursor.y;
|
||||
while (++line < DISPLAY_VCHAR_MAX)
|
||||
{
|
||||
// Update check line.
|
||||
saved_start = start;
|
||||
start = (start - 1 < 0) ? tty.cursor.max.y : start - 1;
|
||||
|
||||
// Check if the line existe.
|
||||
if (tty.buffer[start][0] == '\0')
|
||||
{
|
||||
start = saved_start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Display "on-screen" string lines.
|
||||
i = -1;
|
||||
while (++i < line)
|
||||
{
|
||||
// Set display cursor.
|
||||
display_ioctl(DISPLAY_IOCTL_SETX, 0);
|
||||
display_ioctl(DISPLAY_IOCTL_SETY, i);
|
||||
|
||||
// Get / check line lenght.
|
||||
line_len = strnlen(tty.buffer[start], tty.cursor.max.x);
|
||||
if (line_len == 0)
|
||||
continue;
|
||||
|
||||
// Display line.
|
||||
tty.primitives.write(tty.buffer[start], line_len);
|
||||
|
||||
// Get "next" line.
|
||||
start = (start + 1 > tty.cursor.max.y) ? 0 : start + 1;
|
||||
}
|
||||
|
||||
// Display on screen.
|
||||
display_ioctl(DISPLAY_IOCTL_DISPLAY);
|
||||
|
||||
// Restore display "context"
|
||||
display_ioctl(DISPLAY_IOCTL_SETX, scolumn);
|
||||
display_ioctl(DISPLAY_IOCTL_SETY, srow);
|
||||
|
||||
// End atomic operation
|
||||
atomic_stop();
|
||||
}
|
||||
|
||||
ssize_t tty_write(void *inode, const void *buffer, size_t count)
|
||||
{
|
||||
ssize_t written;
|
||||
|
||||
// Uopdate internal buffer and display
|
||||
// TTY on the screen.
|
||||
written = tty_buffer_update(buffer, count);
|
||||
tty_display();
|
||||
|
||||
// Return the number of char written into
|
||||
// TTY's internal buffer.
|
||||
return (written);
|
||||
}
|
|
@ -1,15 +1,20 @@
|
|||
#include <kernel/devices/tty.h>
|
||||
#include <kernel/devices/display.h>
|
||||
#include <kernel/devices/keyboard.h>
|
||||
#include <kernel/util/string.h>
|
||||
|
||||
// Internal TTY object.
|
||||
struct tty_s tty;
|
||||
|
||||
//TODO: MULTIPLE OPEN !!!!
|
||||
//TODO: SHARED TTY DEVICE !!!!
|
||||
void *tty_open(dev_t major, dev_t minor)
|
||||
{
|
||||
int lines;
|
||||
|
||||
// TODO: handle major / minor ?
|
||||
(void)major;
|
||||
(void)minor;
|
||||
|
||||
// Initialize TTY cursor.
|
||||
tty.cursor.x = 0;
|
||||
tty.cursor.y = 0;
|
||||
|
@ -21,15 +26,5 @@ void *tty_open(dev_t major, dev_t minor)
|
|||
lines = TTY_BUFFER_LINES;
|
||||
while (--lines >= 0)
|
||||
memset(tty.buffer[lines], '\0', TTY_BUFFER_COLUMNS);
|
||||
|
||||
// Set TTY primitives
|
||||
// TODO: Add USB primitives
|
||||
// TODO: update this part.
|
||||
tty.primitives.write = &display_write;
|
||||
tty.primitives.read = &keyboard_read;
|
||||
|
||||
// Call TTY primitives constructor
|
||||
keyboard_open();
|
||||
display_open();
|
||||
return (&tty);
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
#include <kernel/devices/tty.h>
|
||||
#include <kernel/devices/keyboard.h>
|
||||
#include <kernel/context.h>
|
||||
#include <kernel/syscall.h>
|
||||
#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/timer.h>
|
||||
#include <kernel/util/casio.h>
|
||||
#include <kernel/context.h>
|
||||
#include <kernel/syscall.h>
|
||||
|
||||
// Intenral functions
|
||||
static void wait_keyboard_event(void);
|
||||
|
@ -21,15 +21,18 @@ 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;
|
||||
extern struct tty_s tty;
|
||||
struct keycache_s *keynode;
|
||||
struct keyboard_obj_s keyboard;
|
||||
struct tty_s *tty;
|
||||
int first_key;
|
||||
int timer_fd;
|
||||
|
||||
// Check potential error.
|
||||
if (count < 2)
|
||||
return (0);
|
||||
|
||||
// get tty device
|
||||
tty = inode;
|
||||
|
||||
// Initialize internal struc.
|
||||
memset(buffer, '\0', count);
|
||||
|
@ -41,8 +44,8 @@ ssize_t tty_read(void *inode, void *buffer, size_t count)
|
|||
keyboard.cvisible = 0;
|
||||
|
||||
// save TTY informations.
|
||||
keyboard.saved.tty.cursor.x = tty.cursor.x;
|
||||
keyboard.saved.tty.cursor.y = tty.cursor.y;
|
||||
keyboard.saved.tty.cursor.x = tty->cursor.x;
|
||||
keyboard.saved.tty.cursor.y = tty->cursor.y;
|
||||
|
||||
// Initialize timer for cursor.
|
||||
// FIXME: find real ticks value !!
|
||||
|
@ -227,7 +230,6 @@ static int check_special(struct keyboard_obj_s *keyboard, key_t key)
|
|||
|
||||
static void tty_buffer_display(struct keyboard_obj_s *keyboard)
|
||||
{
|
||||
extern struct tty_s tty;
|
||||
size_t size;
|
||||
|
||||
// Restore TTY X/Y axis positions.
|
||||
|
@ -315,7 +317,6 @@ static int buffer_insert(struct keyboard_obj_s *keyboard, char n)
|
|||
|
||||
static void cursor_callback(struct keyboard_obj_s *keyboard)
|
||||
{
|
||||
extern struct tty_s tty;
|
||||
int x;
|
||||
int y;
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
#include <kernel/devices/tty.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
#include <kernel/util/debug.h>
|
||||
#include <kernel/util/string.h>
|
||||
|
||||
/* tty_vertical_update() - Check / update TTY vertical cursor */
|
||||
static void tty_vertical_update(struct tty_s *tty)
|
||||
{
|
||||
// Get next line.
|
||||
tty->cursor.y = 0;
|
||||
if (tty->cursor.y + 1 <= tty->cursor.max.y)
|
||||
tty->cursor.y = tty->cursor.y + 1;
|
||||
|
||||
// Wipe new line.
|
||||
memset(tty->buffer[tty->cursor.y], '\0', tty->cursor.max.x);
|
||||
}
|
||||
|
||||
/* tty_horizontal_update() - Check / update TTY horizotal cursor */
|
||||
static int tty_horizontal_update(struct tty_s *tty)
|
||||
{
|
||||
tty->cursor.x = tty->cursor.x + 1;
|
||||
if (tty->cursor.x >= tty->cursor.max.x)
|
||||
{
|
||||
tty_vertical_update(tty);
|
||||
tty->cursor.x = 0;
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* tty_buffer_update() - Line discipline */
|
||||
static ssize_t tty_buffer_update(struct tty_s *tty, const uint8_t *buffer, size_t count)
|
||||
{
|
||||
int16_t offset;
|
||||
ssize_t i;
|
||||
|
||||
i = -1;
|
||||
while (++i < (ssize_t)count)
|
||||
{
|
||||
// Check bell char.
|
||||
if (buffer[i] == '\a')
|
||||
{
|
||||
// TODO
|
||||
continue;
|
||||
}
|
||||
// Check backspace.
|
||||
if (buffer[i] == '\b')
|
||||
{
|
||||
if (tty->cursor.x > 0)
|
||||
tty->cursor.x = tty->cursor.x - 1;
|
||||
tty->buffer[tty->cursor.y][tty->cursor.x] = '\0';
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check horizotal tab.
|
||||
if (buffer[i] == '\t')
|
||||
{
|
||||
// Check if we need a new line or not.
|
||||
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);
|
||||
tty->cursor.x = tty->cursor.x + offset;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If a new line is required char.
|
||||
// Generate a new line.
|
||||
tty->cursor.x = 0;
|
||||
tty_vertical_update(tty);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check new line char.
|
||||
if (buffer[i] == '\n')
|
||||
{
|
||||
tty->cursor.x = 0;
|
||||
tty_vertical_update(tty);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Check 'form feed' and 'vertical tab' char.
|
||||
// @note: for now this character is interpreted like '\v'
|
||||
if (buffer[i] == '\f' || buffer[i] == '\v')
|
||||
{
|
||||
tty_vertical_update(tty);
|
||||
memset(tty->buffer[tty->cursor.y], ' ', tty->cursor.x);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check carriage return.
|
||||
if (buffer[i] == '\r') { tty->cursor.x = 0; continue;}
|
||||
|
||||
// Update TTY buffer char.
|
||||
tty->buffer[tty->cursor.y][tty->cursor.x] = buffer[i];
|
||||
tty_horizontal_update(tty);
|
||||
}
|
||||
return (i);
|
||||
}
|
||||
|
||||
// FIXME: this function is device-specific !
|
||||
// TODO: Update me ?
|
||||
static void tty_display(struct tty_s *tty)
|
||||
{
|
||||
int saved_start;
|
||||
int line_len;
|
||||
int line;
|
||||
int start;
|
||||
int y;
|
||||
|
||||
// Start atomic operation.
|
||||
atomic_start();
|
||||
|
||||
// Get the "first" line and number of line.
|
||||
// @note: circular buffer.
|
||||
line = 0;
|
||||
start = tty->cursor.y;
|
||||
while (++line < DISPLAY_VCHAR_MAX)
|
||||
{
|
||||
// Update check line.
|
||||
saved_start = start;
|
||||
start = (start - 1 < 0) ? tty->cursor.max.y : start - 1;
|
||||
|
||||
// Check if the line existe.
|
||||
if (tty->buffer[start][0] == '\0')
|
||||
{
|
||||
start = saved_start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
kvram_print(0, y, tty->buffer[start], line_len);
|
||||
|
||||
// Get "next" line.
|
||||
start = (start + 1 > tty->cursor.max.y) ? 0 : start + 1;
|
||||
}
|
||||
|
||||
// Display on screen.
|
||||
kvram_display();
|
||||
|
||||
// Stop atomic operation
|
||||
atomic_stop();
|
||||
}
|
||||
|
||||
/* tty_write() - TTY write primitive ! */
|
||||
ssize_t tty_write(void *inode, const void *buffer, size_t count)
|
||||
{
|
||||
ssize_t written;
|
||||
|
||||
// Update internal buffer and display
|
||||
// TTY on the screen.
|
||||
written = tty_buffer_update(inode, buffer, count);
|
||||
|
||||
// TODO: Monotonic display ?
|
||||
tty_display(inode);
|
||||
|
||||
// Return the number of char written into
|
||||
// TTY's internal buffer.
|
||||
return (written);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
#include <kernel/drivers/keyboard.h>
|
||||
|
||||
/*
|
||||
** Internal cache, used like chained list.
|
||||
**
|
||||
** @note:
|
||||
** The KEYSC have 6 key data 16-bits registers
|
||||
** this is why we used 6 * 16 = 96 cache slot.
|
||||
*/
|
||||
struct keycache_s keycache[96];
|
||||
struct keycache_s *keylist;
|
||||
|
||||
/*
|
||||
** keycache_init()
|
||||
**
|
||||
** @info
|
||||
** Constructor used by the kernel during the
|
||||
** bootstrap part. It will initialize keycache
|
||||
** and the chained list.
|
||||
** This function sould not be called anymore.
|
||||
*/
|
||||
__attribute__((constructor))
|
||||
static void keycache_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 96;
|
||||
while (--i >= 0)
|
||||
{
|
||||
keycache[i].keycode = KEY_UNUSED;
|
||||
keycache[i].next = NULL;
|
||||
}
|
||||
keylist = NULL;
|
||||
}
|
|
@ -1,30 +1,37 @@
|
|||
#include <kernel/devices/keyboard.h>
|
||||
|
||||
// Internal cache, used like chained list.
|
||||
// @note:
|
||||
// The KEYSC have 6 key data 16-bits registers
|
||||
// this is why we used 6 * 16 = 96 cache slot.
|
||||
static struct keycache_s keycache[96];
|
||||
|
||||
// chained list.
|
||||
// FIXME: avoid reentrace
|
||||
struct keycache_s *keylist;
|
||||
#include <kernel/drivers/keyboard.h>
|
||||
#include <kernel/util/atomic.h>
|
||||
|
||||
/* keycache_alloc() - Try to alloc a new keycache node */
|
||||
static struct keycache_s *keycache_alloc(void)
|
||||
{
|
||||
extern struct keycache_s keycache[96];
|
||||
void *node;
|
||||
int i;
|
||||
|
||||
// Start atomic operations
|
||||
atomic_start();
|
||||
|
||||
// Try to find free slot
|
||||
i = 96;
|
||||
node = NULL;
|
||||
while (--i >= 0)
|
||||
{
|
||||
if (keycache[i].keycode == KEY_UNUSED)
|
||||
return (&keycache[i]);
|
||||
{
|
||||
node = &keycache[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
|
||||
// Stop atomic operations
|
||||
atomic_stop();
|
||||
return (node);
|
||||
}
|
||||
|
||||
/* keycache_update() - Add / update key code node */
|
||||
void keycache_update(int row, int column, uint8_t key_frame)
|
||||
{
|
||||
extern struct keycache_s *keylist;
|
||||
struct keycache_s *current_node;
|
||||
struct keycache_s *new_node;
|
||||
uint8_t keycode;
|
||||
|
@ -32,6 +39,9 @@ void keycache_update(int row, int column, uint8_t key_frame)
|
|||
// Generate keycode.
|
||||
keycode = KEYCODE_GEN(row, column);
|
||||
|
||||
// Start atomic operations
|
||||
atomic_start();
|
||||
|
||||
// Try to fint the key node.
|
||||
current_node = keylist;
|
||||
while (current_node != NULL)
|
||||
|
@ -40,6 +50,7 @@ void keycache_update(int row, int column, uint8_t key_frame)
|
|||
if (current_node->keycode == keycode)
|
||||
{
|
||||
current_node->key_frame = key_frame;
|
||||
atomic_stop();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -49,25 +60,33 @@ void keycache_update(int row, int column, uint8_t key_frame)
|
|||
|
||||
// If no node is found, create new node.
|
||||
new_node = keycache_alloc();
|
||||
if (new_node == NULL)
|
||||
return;
|
||||
if (new_node != NULL)
|
||||
{
|
||||
// Fill new node
|
||||
new_node->keycode = keycode;
|
||||
new_node->key_frame = key_frame;
|
||||
new_node->counter = 0;
|
||||
|
||||
// Fill new node
|
||||
new_node->keycode = keycode;
|
||||
new_node->key_frame = key_frame;
|
||||
new_node->counter = 0;
|
||||
// And place it on the first node because
|
||||
// the first node designates the last key
|
||||
// pressed.
|
||||
new_node->next = keylist;
|
||||
keylist = new_node;
|
||||
}
|
||||
|
||||
// And place it on the first node because
|
||||
// the first node designates the last key
|
||||
// pressed.
|
||||
new_node->next = keylist;
|
||||
keylist = new_node;
|
||||
// Stop atomic operations
|
||||
atomic_stop();
|
||||
}
|
||||
|
||||
/* keycache_clean() - Remove dirty node */
|
||||
void keycache_clean(int key_frame)
|
||||
{
|
||||
extern struct keycache_s *keylist;
|
||||
struct keycache_s **current_node;
|
||||
|
||||
// Start atomic operations
|
||||
atomic_start();
|
||||
|
||||
current_node = &keylist;
|
||||
while (*current_node != NULL)
|
||||
{
|
||||
|
@ -85,18 +104,7 @@ void keycache_clean(int key_frame)
|
|||
(*current_node)->counter = (*current_node)->counter + 1;
|
||||
current_node = &(*current_node)->next;
|
||||
}
|
||||
}
|
||||
|
||||
// Contructor.
|
||||
void keycache_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 96;
|
||||
while (--i >= 0)
|
||||
{
|
||||
keycache[i].keycode = KEY_UNUSED;
|
||||
keycache[i].next = NULL;
|
||||
}
|
||||
keylist = NULL;
|
||||
// Stop atomic operations
|
||||
atomic_stop();
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
#include <kernel/hardware/tmu.h>
|
||||
#include <kernel/util/timer.h>
|
||||
#include <kernel/drivers/timer.h>
|
||||
|
||||
void timer_handler(void)
|
||||
{
|
|
@ -1,56 +0,0 @@
|
|||
#include <kernel/devices/ubc.h>
|
||||
#include <kernel/devices/display.h>
|
||||
#include <kernel/hardware/ubc.h>
|
||||
#include <kernel/syscall.h>
|
||||
#include <kernel/util/extra.h>
|
||||
|
||||
|
||||
// Internal function.
|
||||
extern void menu_context(ubc_session_t *session);
|
||||
extern void menu_disassembly(ubc_session_t *session);
|
||||
|
||||
void ubc_module_handler(int action)
|
||||
{
|
||||
/* dclear();
|
||||
dprint(0, 0, "spc = %p", action);
|
||||
dupdate();
|
||||
for (int i = 0 ; i < 4000000 ; i = i + 1);
|
||||
|
||||
*/ //TODO stop all clock / timer.
|
||||
}
|
||||
|
||||
void ubc_handler(struct ubc_context_s *context, int channel)
|
||||
{
|
||||
/* void (*menu)(ubc_session_t *session);
|
||||
ubc_session_t session;
|
||||
|
||||
// Initialize new session.
|
||||
session.key = 0;
|
||||
session.channel = channel;
|
||||
session.context = context;
|
||||
session.menu.context.cursor = 0;
|
||||
session.menu.disassembly.vcursor = -(DISPLAY_VCHAR_MAX >> 1);
|
||||
session.menu.disassembly.hcursor = 0;
|
||||
|
||||
// Initialize menu function.
|
||||
menu = &menu_disassembly;
|
||||
|
||||
// Main loop.
|
||||
while (session.key != KEY_CTRL_EXIT)
|
||||
{
|
||||
menu(&session);
|
||||
casio_GetKey(&session.key);
|
||||
switch (session.key)
|
||||
{
|
||||
case KEY_CTRL_F1: menu = &menu_disassembly; break;
|
||||
case KEY_CTRL_F2: menu = &menu_context; break;
|
||||
}
|
||||
}*/
|
||||
|
||||
// Update UBC
|
||||
SH7305_UBC.CBR0.CE = 0; // Disable channel.
|
||||
// SH7305_UBC.CAR0 = context->spc; // Update break address.
|
||||
// SH7305_UBC.CAMR0 = 0x00000000; // Update break address.
|
||||
// SH7305_UBC.CBR0.CE = 1; // Enable channel.
|
||||
icbi((void*)0xa0000000);
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
.section ".ubc.handler", "awx", @progbits
|
||||
|
||||
.global _ubc_handler_pre
|
||||
.type _ubc_handler_pre, @function
|
||||
|
||||
.extern _ubc_handler
|
||||
.extern _ubc_module_handler
|
||||
|
||||
|
||||
.align 2
|
||||
_ubc_handler_pre:
|
||||
! Stack management.
|
||||
mov.l r9, @-r15 ! Save r9 register.
|
||||
mov.l r8, @-r15 ! Save r8 register.
|
||||
sts.l pr, @-r15 ! Save pr regsiter.
|
||||
|
||||
! Generate "programe" context (used by the UBC handler)
|
||||
stc.l spc, @-r15 ! Get SPC register.
|
||||
stc.l ssr, @-r15 ! Get SSR register.
|
||||
sts.l mach, @-r15 ! Get MACH register.
|
||||
sts.l macl, @-r15 ! Get MACL register.
|
||||
stc.l gbr, @-r15 ! Get GBR register.
|
||||
.word 0b0100111100110010 ! Get SGR register (save r15 address befor break) "stc.l sgr, @-r15"
|
||||
mov.l r14, @-r15 ! Get "program" r14 register.
|
||||
mov.l r13, @-r15 ! Get "program" r13 register.
|
||||
mov.l r12, @-r15 ! Get "program" r12 register.
|
||||
mov.l r11, @-r15 ! Get "program" r11 register.
|
||||
mov.l r10, @-r15 ! Get "program" r10 register.
|
||||
mov.l r9, @-r15 ! Get "program" r9 register.
|
||||
mov.l r8, @-r15 ! Get "program" r8 register.
|
||||
stc.l R7_BANK, @-r15 ! Get "program" r7 regsiter.
|
||||
stc.l R6_BANK, @-r15 ! Get "program" r6 regsiter.
|
||||
stc.l R5_BANK, @-r15 ! Get "program" r5 regsiter.
|
||||
stc.l R4_BANK, @-r15 ! Get "program" r4 regsiter.
|
||||
stc.l R3_BANK, @-r15 ! Get "program" r3 regsiter.
|
||||
stc.l R2_BANK, @-r15 ! Get "program" r2 regsiter.
|
||||
stc.l R1_BANK, @-r15 ! Get "program" r1 regsiter.
|
||||
stc.l R0_BANK, @-r15 ! Get "program" r0 regsiter.
|
||||
|
||||
! We need to stop (and save) all clocks / timers
|
||||
! before do any job.
|
||||
mov.l .ubc_module_handler, r0 ! Get high level abstraction for handle hardware module.
|
||||
jsr @r0 ! call ubc_module(MODULE_STOP)
|
||||
mov #0, r4 ! (db) r4 = MODULE_STOP
|
||||
|
||||
! Get which channel is trigger and clear interrupt Flags.
|
||||
mov.l .ubc_ccmfr, r0 ! Get UBC.CCMFR register
|
||||
mov.l @r0, r9 ! r5 = UBC.CCMFR. (save register)
|
||||
mov #0, r1 ! r2 = 0x00000000 (clear flags)
|
||||
mov.l r1, @r0 ! Clear UBC.CCMFR.MF1 = 0 and UBC.CCMFR.MF1 = 0
|
||||
mov.l .icbi_addr, r2 ! Get P2 area for ICBI instruction.
|
||||
.word 0b0000001011100011 ! SH4 instruction "icbi @r2"
|
||||
|
||||
! Allow / unblock interrupt and switch register bank !
|
||||
stc sr, r8 ! Save SR register.
|
||||
mov r8, r1 ! Get SR register.
|
||||
mov.l .sr_mask, r0 ! Get SR mask for SR.BL, SR.IMASK and SR.RB
|
||||
and r0, r1 ! SR.BL = 0, SR.IMASK = 0b0000 and SR.RB = 0
|
||||
ldc r1, sr ! Update SR register.
|
||||
|
||||
! Call high-level abstraction
|
||||
mov r15, r4 ! Send UBC context object to the abstraction.
|
||||
mov r9, r5 ! Send which channel is trigger.
|
||||
mov.l .ubc_handler, r0 ! Get high-level abstraction address
|
||||
jsr @r0 ! Jump into it.
|
||||
nop ! (db) nop.
|
||||
|
||||
! Block interrupt and switch
|
||||
! register bank
|
||||
ldc r8, sr ! Restore SR register (with SR.BL = 1, SR.IMASK = 0b1111, SR.RB = 1)
|
||||
|
||||
! Restore "program" context.
|
||||
ldc.l @r15+, R0_BANK ! Restore "program" r0 regsiter.
|
||||
ldc.l @r15+, R1_BANK ! Restore "program" r1 regsiter.
|
||||
ldc.l @r15+, R2_BANK ! Restore "program" r2 regsiter.
|
||||
ldc.l @r15+, R3_BANK ! Restore "program" r3 regsiter.
|
||||
ldc.l @r15+, R4_BANK ! Restore "program" r4 regsiter.
|
||||
ldc.l @r15+, R5_BANK ! Restore "program" r5 regsiter.
|
||||
ldc.l @r15+, R6_BANK ! Restore "program" r6 regsiter.
|
||||
ldc.l @r15+, R7_BANK ! Restore "program" r7 regsiter.
|
||||
mov.l @r15+, r8 ! Restore "program" r8 regsiter.
|
||||
mov.l @r15+, r9 ! Restore "program" r9 regsiter.
|
||||
mov.l @r15+, r10 ! Restore "program" r10 regsiter.
|
||||
mov.l @r15+, r11 ! Restore "program" r11 regsiter.
|
||||
mov.l @r15+, r12 ! Restore "program" r12 regsiter.
|
||||
mov.l @r15+, r13 ! Restore "program" r13 regsiter.
|
||||
mov.l @r15+, r14 ! Restore "program" r14 regsiter.
|
||||
.word 0b0100111100110110 ! Restore SGR regsiter. "ldc.l @r15+, sgr"
|
||||
ldc.l @r15+, gbr ! Get GBR register.
|
||||
lds.l @r15+, macl ! Get MACL register.
|
||||
lds.l @r15+, mach ! Get MACH register.
|
||||
ldc.l @r15+, ssr ! Restore SSR regsiter.
|
||||
ldc.l @r15+, spc ! Restore SPC regsiter.
|
||||
|
||||
! Retore and restart clock / timers
|
||||
stc spc, r4 ! (db) r4 = MODULE_START
|
||||
mov.l .ubc_module_handler, r0 ! Get high level abstraction for handle hardware module.
|
||||
jsr @r0 ! call ubc_module(MODULE_START)
|
||||
nop
|
||||
|
||||
! Clean exit.
|
||||
lds.l @r15+, pr ! Restor PR register.
|
||||
mov.l @r15+, r8 ! Restore r8 register.
|
||||
mov.l @r15+, r9 ! Restore r8 register.
|
||||
rte ! Interrupt Exit.
|
||||
nop ! (db) Safety first.
|
||||
|
||||
|
||||
.align 4
|
||||
.ubc_handler: .long _ubc_handler
|
||||
.ubc_module_handler: .long _ubc_module_handler
|
||||
.ubc_ccmfr: .long 0xff200600
|
||||
.icbi_addr: .long 0xa0000000
|
||||
.sr_mask: .long ~(0x300000f0)
|
||||
.end
|
Loading…
Reference in New Issue