Updated project organization to isolate kernel, libraries and user applications
This commit is contained in:
parent
145e75088c
commit
6c0971e661
110
Makefile
110
Makefile
|
@ -2,105 +2,24 @@
|
|||
## ---
|
||||
## Project: Vhex - On-calc debugger
|
||||
## Author: yann.magnin@epitech.eu
|
||||
## ---
|
||||
|
||||
##---
|
||||
## Static variables
|
||||
##--
|
||||
HEADER := -Iinclude -Iinclude/user
|
||||
BUILD := build
|
||||
DEBUG := debug
|
||||
|
||||
NAME := vhex
|
||||
EXEC := $(NAME).g1a
|
||||
LDFLAG := -T $(NAME).ld
|
||||
MEMORY_MAP := $(DEBUG)/$(NAME).map
|
||||
ICON := icon.bmp
|
||||
|
||||
|
||||
COMPILER := sh3eb-elf-
|
||||
CC := $(COMPILER)gcc
|
||||
OBJCOPY := $(COMPILER)objcopy
|
||||
OBJDUMP := $(COMPILER)objdump
|
||||
WRAPPER := g1a-wrapper
|
||||
CFLAGS := -Werror -Wall -W -Wextra -std=c18 -m3 -mb -mrenesas \
|
||||
-ffreestanding -nostdlib -fstrict-volatile-bitfields \
|
||||
-Wno-unused-const-variable -Wno-unused-function \
|
||||
-Wno-unused-variable -Wno-unused-but-set-variable \
|
||||
-Wno-unused-parameter
|
||||
|
||||
|
||||
red := \033[1;31m
|
||||
green := \033[1;32m
|
||||
blue := \033[1;34m
|
||||
white := \033[1;37m
|
||||
nocolor := \033[1;0m
|
||||
|
||||
|
||||
|
||||
|
||||
##---
|
||||
## Automated variables
|
||||
##---
|
||||
SRC :=
|
||||
DIRECTORY := $(shell find src -not -path "*/\.*" -type d)
|
||||
# Get all source files
|
||||
$(foreach path,$(DIRECTORY),$(eval \
|
||||
SRC += $(wildcard $(path)/*.c) \
|
||||
$(wildcard $(path)/*.S) \
|
||||
$(wildcard $(path)/*.s) \
|
||||
))
|
||||
# Geneate all object files
|
||||
OBJ := $(patsubst %,$(BUILD)/%.o,$(subst /,_,$(subst src/,,$(basename $(SRC)))))
|
||||
## ---
|
||||
|
||||
|
||||
KERNEL := output/vhex.g1a
|
||||
USER := output/shell.elf
|
||||
|
||||
|
||||
##---
|
||||
## General rules
|
||||
##---
|
||||
all: | $(BUILD) $(DEBUG) $(EXEC)
|
||||
all:
|
||||
@ make --no-print-directory -C src/kernel
|
||||
@ make --no-print-directory -C src/lib
|
||||
@ make --no-print-directory -C src/user
|
||||
|
||||
$(EXEC): $(OBJ)
|
||||
$(CC) -Wl,-M $(LDFLAG) $(CFLAGS) -o $(DEBUG)/$(NAME).elf $(OBJ) $(HEADER) -lgcc > $(MEMORY_MAP)
|
||||
$(OBJCOPY) -R .comment -R .bss -O binary $(DEBUG)/$(NAME).elf $(DEBUG)/$(NAME).bin
|
||||
$(WRAPPER) $(DEBUG)/$(NAME).bin -o $@ -i $(ICON)
|
||||
|
||||
$(BUILD) $(DEBUG):
|
||||
@ printf "Create $(blue)$@$(nocolor) directory\n"
|
||||
@ mkdir -p $@
|
||||
|
||||
install: $(EXEC)
|
||||
sudo p7 send --force $^
|
||||
|
||||
check:
|
||||
@ echo 'src: $(SRC)'
|
||||
@ echo 'obj: $(OBJ)'
|
||||
@ echo 'directory: $(DIRECTORY)'
|
||||
|
||||
asm:
|
||||
@ $(OBJDUMP) -D $(DEBUG)/$(NAME).elf | less
|
||||
|
||||
map:
|
||||
@ cat $(MEMORY_MAP) | less
|
||||
|
||||
sec:
|
||||
@ $(OBJDUMP) -h $(DEBUG)/$(NAME).elf
|
||||
|
||||
|
||||
##---
|
||||
## Automated rules
|
||||
##---
|
||||
define rule-src
|
||||
$(patsubst %,$(BUILD)/%.o,$(subst /,_,$(subst src/,,$(basename $1)))): $1
|
||||
@ printf "compiling $(white)$$<$(nocolor)..."
|
||||
@ $(CC) $(CFLAGS) -o $$@ -c $$< $(HEADER) -lgcc
|
||||
@ printf "$(green)[ok]$(nocolor)\n"
|
||||
endef
|
||||
|
||||
$(foreach source,$(SRC),$(eval \
|
||||
$(call rule-src,$(source))) \
|
||||
)
|
||||
install: all
|
||||
sudo p7 send --force --no-term $(KERNEL)
|
||||
sudo p7 send --force --directory=VHEX $(USER)
|
||||
|
||||
|
||||
|
||||
|
@ -109,11 +28,14 @@ $(foreach source,$(SRC),$(eval \
|
|||
## Cleaning rules
|
||||
##---
|
||||
clean:
|
||||
rm -rf $(BUILD)
|
||||
rm -rf $(DEBUG)
|
||||
make clean --no-print-directory -C src/kernel
|
||||
make clean --no-print-directory -C src/lib
|
||||
make clean --no-print-directory -C src/user
|
||||
|
||||
fclean: clean
|
||||
rm -f $(EXEC)
|
||||
make fclean --no-print-directory -C src/kernel
|
||||
make fclean --no-print-directory -C src/lib
|
||||
make fclean --no-print-directory -C src/user
|
||||
|
||||
re: fclean all
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
# Global option use in each Makefile
|
||||
|
||||
# Tools
|
||||
COMPILER := sh3eb-elf-
|
||||
CC := $(COMPILER)gcc
|
||||
OBJCOPY := $(COMPILER)objcopy
|
||||
OBJDUMP := $(COMPILER)objdump
|
||||
WRAPPER := g1a-wrapper
|
||||
|
||||
# Flags
|
||||
CFLAGS := -Werror -Wall -W -Wextra -std=c18 -m3 -mb -mrenesas \
|
||||
-ffreestanding -nostdlib -fstrict-volatile-bitfields \
|
||||
-Wno-unused-const-variable -Wno-unused-function \
|
||||
-Wno-unused-variable -Wno-unused-but-set-variable \
|
||||
-Wno-unused-parameter
|
||||
|
||||
# Colors
|
||||
red := \033[1;31m
|
||||
green := \033[1;32m
|
||||
blue := \033[1;34m
|
||||
white := \033[1;37m
|
||||
nocolor := \033[1;0m
|
||||
|
||||
|
||||
define n
|
||||
# Force newline character
|
||||
|
||||
endef
|
|
@ -46,6 +46,7 @@ typedef struct fx9860_context_s
|
|||
} timer[3];
|
||||
} tmu;
|
||||
uint32_t vbr;
|
||||
//TODO: SR SSR SPC GBR MACL MACH
|
||||
} fx9860_context_t;
|
||||
|
||||
typedef struct common_context_s
|
||||
|
@ -56,6 +57,7 @@ typedef struct common_context_s
|
|||
uint32_t mach;
|
||||
uint32_t ssr;
|
||||
uint32_t spc;
|
||||
uint32_t pr;
|
||||
} common_context_t;
|
||||
|
||||
// Context primitive.
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef __FILE_H__
|
||||
# define __FILE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef FILE_OPEN_NUMBER
|
||||
# define FILE_OPEN_NUMBER 4
|
||||
#endif
|
||||
|
||||
struct file_s
|
||||
{
|
||||
void *abstract;
|
||||
off_t cursor;
|
||||
uint8_t mode;
|
||||
size_t size;
|
||||
};
|
||||
typedef struct file_s FILE;
|
||||
|
||||
#endif /*__FILE_H__*/
|
|
@ -0,0 +1,89 @@
|
|||
#ifndef __CASIO_SMEM_H__
|
||||
# define __CASIO_SMEM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <kernel/types.h>
|
||||
#include <kernel/fs/file.h>
|
||||
|
||||
|
||||
#define CASIO_SMEM_NAME_LENGHT 12
|
||||
#define CASIO_SMEM_ROOT_ID 0xffff
|
||||
#define CASIO_SMEM_BLOCK_ENTRY_MAGIC 0x4200
|
||||
#define CASIO_SMEM_HEADER_INFO_EXIST 0x51
|
||||
#define CASIO_SMEM_HEADER_INFO_DELETE 0x01
|
||||
#define CASIO_SMEM_HEADER_TYPE_DIRECTORY 0x10
|
||||
#define CASIO_SMEM_HEADER_TYPE_FILE 0x20
|
||||
#define CASIO_SMEM_FRAGMENT_INFO_EXIST CASIO_SMEM_HEADER_INFO_EXIST
|
||||
#define CASIO_SMEM_FRAGMENT_INFO_DELETE CASIO_SMEM_HEADER_INFO_DELETE
|
||||
#define CASIO_SMEM_FRAGMENT_MAGIC 0x0120
|
||||
|
||||
#define CASIO_SMEM_ROOT_ID 0xffff
|
||||
|
||||
#define O_RDONLY 0x00
|
||||
#define O_WRONLY 0x01
|
||||
#define O_RDWR 0x02
|
||||
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_END 2
|
||||
|
||||
//
|
||||
typedef struct casio_smem_block_s
|
||||
{
|
||||
uint16_t magic_start; // always 0x4200
|
||||
uint16_t entry_number; // indicate the block number
|
||||
uint32_t offset; // offset in the memory (?)
|
||||
|
||||
struct {
|
||||
uint8_t used; // Indicate if the block is used (0xff yes, 0x00 no)
|
||||
uint8_t fileTable; // Indicate if the block is used by File Header Table.
|
||||
uint16_t id; // Indicate the block ID in the File Header Table.
|
||||
} info;
|
||||
|
||||
uint8_t magic_end[20]; // Content always 0xff 0xff 0xff 0xff 0x00 0x00 0x00 0x01 0xff 0xff...
|
||||
} casio_smem_block_t;
|
||||
|
||||
// Define file header.
|
||||
typedef struct casio_smem_header_s
|
||||
{
|
||||
uint8_t info; // 0x51 if entry exist, 0x01 if entry refer to delete file. (?)
|
||||
uint8_t type; // 0x10 for a directory, 0x20 for preheader.
|
||||
uint16_t id; // Indicate the block entry ID (directory)
|
||||
|
||||
struct {
|
||||
uint16_t type; // 0xffff for root, 0x0110 for directory
|
||||
uint16_t id; // directory ID, 0xffff for root
|
||||
} parent;
|
||||
|
||||
uint16_t name[12]; // File name
|
||||
} casio_smem_header_t;
|
||||
|
||||
// Define frament data.
|
||||
typedef struct casio_smem_fragment_s
|
||||
{
|
||||
uint8_t info; // 0x51 if entry exit, 0x01 if entry refer to delete file.
|
||||
uint8_t unknown0; // always 0x30
|
||||
uint16_t id; // Fragment ID.
|
||||
uint16_t magic; // always 0x0120
|
||||
uint16_t file_id; // File ID.
|
||||
uint16_t unknown1; // 0x0002 (?)
|
||||
uint16_t frag_total; // total number of fragments for this file.
|
||||
uint16_t frag_current_number; // Current fragment number.
|
||||
uint16_t data_block_id; // ID of blocks containing data for this fragment
|
||||
uint16_t data_offset; // offset of fragment data in the given block
|
||||
|
||||
// WARNING : the size is (real_size-1), so *do not forget* to add 1 to
|
||||
// have the real size of data!
|
||||
uint16_t data_size; // size of this fragment data
|
||||
|
||||
uint8_t fill[12]; // 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ...
|
||||
} casio_smem_fragment_t;
|
||||
|
||||
// Primitives
|
||||
extern int casio_smem_mount(void);
|
||||
extern int casio_smem_open(FILE *file, char const *name, int mode);
|
||||
extern ssize_t casio_smem_read(FILE *file, void *buf, size_t count);
|
||||
extern off_t casio_smem_lseek(FILE *file, off_t offset, int whence);
|
||||
|
||||
#endif /*_CASIO_SMEM_H__*/
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef __KERNEL_LOADER_H__
|
||||
# define __KERNEL_LOADER_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Function
|
||||
extern void *loader(const char *path);
|
||||
|
||||
#endif /*__KERNEL_LOADER_H__*/
|
|
@ -6,6 +6,7 @@
|
|||
#include <kernel/context.h>
|
||||
#include <kernel/types.h>
|
||||
|
||||
#define PROCESS_STACK_SIZE (2048)
|
||||
#define PROCESS_NAME_LENGHT (16)
|
||||
#define PROCESS_MAX (3)
|
||||
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
#ifndef __KERNEL_UNISTD_32_H__
|
||||
# define __KERNEL_UNISTD_32_H__
|
||||
|
||||
#define __NR_restart_syscall 0
|
||||
#define __NR_exit 1
|
||||
#define __NR_fork 2
|
||||
#define __NR_read 3
|
||||
#define __NR_write 4
|
||||
#define __NR_open 5
|
||||
#define __NR_close 6
|
||||
#define __NR_waitpid 7
|
||||
#define __NR_restart_syscall 0
|
||||
#define __NR_exit 1
|
||||
#define __NR_exec 2
|
||||
#define __NR_read 3
|
||||
#define __NR_write 4
|
||||
#define __NR_open 5
|
||||
#define __NR_close 6
|
||||
#define __NR_waitpid 7
|
||||
|
||||
// Custom !
|
||||
#define __NR_kvram_display 8
|
||||
#define __NR_kvram_clear 9
|
||||
#define __NR_kvram_print 10
|
||||
#define __NR_kvram_ascii 11
|
||||
#define __NR_kvram_reverse 12
|
||||
#define __NR_kvram_scroll 13
|
||||
|
||||
#endif /*__KERNEL_UNISTD_32_H__*/
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef __KERNEL_UTIL_H__
|
||||
# define __KERNEL_UTIL_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// String function
|
||||
extern void *memset(void *s, int c, size_t n);
|
||||
extern void *memcpy(void *dest, const void *src, size_t count);
|
||||
extern char *strncpy(char *dest, char const *str, size_t size);
|
||||
extern size_t strnlen(char const *str, size_t maxlen);
|
||||
|
||||
// Video RAM functions
|
||||
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_print(int x, int y, char const *str, ...);
|
||||
extern void kvram_ascii(int x, int y, char const c);
|
||||
|
||||
// Hardware specific function (do not use !)
|
||||
extern void t6k11_display(void *vram);
|
||||
|
||||
// Timer functions.
|
||||
extern int timer_uninstall(int timer_ID);
|
||||
extern int timer_install(void *callback, void *arg, uint32_t delay_ms, uint8_t mode);
|
||||
|
||||
#endif /*__KERNEL_UTIL_H__*/
|
|
@ -1,11 +0,0 @@
|
|||
#ifndef __LIB_TIMER_H__
|
||||
# define __LIB_TIMER_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Internal functions.
|
||||
extern int timer_install(void *callback, void *arg, uint32_t delay_ms, uint8_t mode);
|
||||
extern int timer_uninstall(int timer_ID);
|
||||
|
||||
#endif /*__LIB_TIMER_H__*/
|
|
@ -0,0 +1,116 @@
|
|||
#!/usr/bin/make -f
|
||||
## ---
|
||||
## Project: Vhex - Kernel for fx9860
|
||||
## Author: yann.magnin@epitech.eu
|
||||
## ---
|
||||
include ../../global.mk
|
||||
|
||||
|
||||
|
||||
|
||||
##---
|
||||
## Static variables
|
||||
##--
|
||||
HEADER := -I../../include
|
||||
BUILD := ../../build/kernel
|
||||
OUTPUT := ../../output
|
||||
DEBUG := ../../debug
|
||||
|
||||
NAME := vhex
|
||||
EXEC := $(OUTPUT)/$(NAME).g1a
|
||||
LDFLAG := -T $(NAME).ld
|
||||
MEMORY_MAP := $(DEBUG)/$(NAME).map
|
||||
ICON := icon.bmp
|
||||
|
||||
|
||||
|
||||
|
||||
##---
|
||||
## Automated variables
|
||||
##---
|
||||
# Get all directory
|
||||
SRC :=
|
||||
DIRECTORY := $(shell find . -not -path "*/\.*" -type d)
|
||||
# Get all source files
|
||||
$(foreach path,$(DIRECTORY),$(eval \
|
||||
SRC += $$(wildcard $(path)/*.c) $n\
|
||||
SRC += $$(wildcard $(path)/*.S) $n\
|
||||
SRC += $$(wildcard $(path)/*.s) $n\
|
||||
))
|
||||
# Geneate all object files
|
||||
OBJ := $(patsubst ._%,$(BUILD)/%.o,$(subst /,_,$(basename $(SRC))))
|
||||
|
||||
|
||||
|
||||
|
||||
##---
|
||||
## General rules
|
||||
##---
|
||||
all: | $(BUILD) $(DEBUG) $(OUTPUT) $(EXEC)
|
||||
|
||||
$(EXEC): $(OBJ)
|
||||
$(CC) -Wl,-M $(LDFLAG) $(CFLAGS) -o $(DEBUG)/$(NAME).elf $(OBJ) $(HEADER) -lgcc > $(MEMORY_MAP)
|
||||
$(OBJCOPY) -R .comment -R .bss -O binary $(DEBUG)/$(NAME).elf $(DEBUG)/$(NAME).bin
|
||||
$(WRAPPER) $(DEBUG)/$(NAME).bin -o $@ -i $(ICON)
|
||||
|
||||
$(BUILD) $(DEBUG) $(OUTPUT):
|
||||
@ printf "Create $(blue)$@$(nocolor) directory\n"
|
||||
@ mkdir -p $@
|
||||
|
||||
|
||||
|
||||
|
||||
##---
|
||||
## Debugging rules
|
||||
##---
|
||||
debug:
|
||||
@ echo 'src: $(SRC)'
|
||||
@ echo 'obj: $(OBJ)'
|
||||
@ echo 'directory: $(DIRECTORY)'
|
||||
|
||||
asm:
|
||||
@ $(OBJDUMP) -D $(DEBUG)/$(NAME).elf | less
|
||||
|
||||
map:
|
||||
@ cat $(MEMORY_MAP) | less
|
||||
|
||||
sec:
|
||||
@ $(OBJDUMP) -h $(DEBUG)/$(NAME).elf
|
||||
|
||||
|
||||
|
||||
|
||||
##---
|
||||
## Automated rules
|
||||
##---
|
||||
define rule-src
|
||||
$(patsubst ._%,$(BUILD)/%.o,$(subst /,_,$(basename $1))): $1
|
||||
@ printf "compiling $(white)$$<$(nocolor)..."
|
||||
@ $(CC) $(CFLAGS) -o $$@ -c $$< $(HEADER) -lgcc
|
||||
@ printf "$(green)[ok]$(nocolor)\n"
|
||||
endef
|
||||
|
||||
$(foreach source,$(SRC),$(eval \
|
||||
$(call rule-src,$(source))) \
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
##---
|
||||
## Cleaning rules
|
||||
##---
|
||||
clean:
|
||||
rm -rf $(BUILD)
|
||||
rm -rf $(DEBUG)
|
||||
|
||||
fclean: clean
|
||||
rm -f $(EXEC)
|
||||
|
||||
re: fclean all
|
||||
|
||||
|
||||
|
||||
|
||||
.PHONY: re fclean clean all
|
||||
.PHONY: debug asm map sec
|
|
@ -4,8 +4,12 @@
|
|||
#include <kernel/atomic.h>
|
||||
#include <kernel/types.h>
|
||||
#include <kernel/process.h>
|
||||
#include <lib/display.h>
|
||||
#include <lib/string.h>
|
||||
#include <kernel/syscall.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
//TODO: remove me !
|
||||
#include <kernel/fs/smem.h>
|
||||
#include <kernel/loader.h>
|
||||
|
||||
// Internal symbols
|
||||
mpu_t current_mpu = MPU_UNKNOWN;
|
||||
|
@ -77,6 +81,7 @@ static void section_execute(void *bsection, void *esection)
|
|||
__attribute__((section(".pretext")))
|
||||
int start(void)
|
||||
{
|
||||
extern uint32_t vram[256];
|
||||
int error;
|
||||
|
||||
// Wipe .bss section and dump .data / Vhex sections
|
||||
|
@ -102,6 +107,10 @@ int start(void)
|
|||
// before switching the VBR.
|
||||
rom_explore(&brom, (int32_t)&srom);
|
||||
|
||||
// Mount Casio FS
|
||||
// TODO: Use Virtual File System !
|
||||
casio_smem_mount();
|
||||
|
||||
// Save Casio's hardware context and set
|
||||
// Vhex hardware context.
|
||||
// @note:
|
||||
|
@ -121,11 +130,40 @@ int start(void)
|
|||
uint32_t ssr = atomic_start();
|
||||
pid_t vhex_pid = process_create("Vhex");
|
||||
process_t *vhex_process = process_get(vhex_pid);
|
||||
vhex_process->context.spc = (uint32_t)&main;
|
||||
|
||||
// Initialize CPU configuration for the process.
|
||||
vhex_process->context.ssr = ssr;
|
||||
|
||||
// Load programe.
|
||||
vhex_process->context.spc = (uint32_t)loader("VHEX/shell.elf");
|
||||
if (vhex_process->context.spc == 0x00000000)
|
||||
{
|
||||
// Display message.
|
||||
kvram_clear();
|
||||
kvram_print(0, 0, "Vhex fatal error !");
|
||||
kvram_print(0, 1, "File \"VHEX/shell.elf\" not found !");
|
||||
kvram_print(0, 2, "Press [MENU key]...");
|
||||
kvram_display();
|
||||
|
||||
// Restore Casio context.
|
||||
fx9860_context_restore(&casio_context);
|
||||
atomic_end();
|
||||
|
||||
// Casio VRAM workaround
|
||||
// @note: GetKey call Bdisp_PutDD_VRAM()
|
||||
memcpy(casio_Bdisp_GetVRAM(), vram, 1024);
|
||||
|
||||
// Wait MENU key.
|
||||
unsigned int key;
|
||||
while (1)
|
||||
{
|
||||
casio_GetKey(&key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Switch to first process.
|
||||
kernel_switch(&vhex_process->context);
|
||||
//kernel_switch(&vhex_process->context);
|
||||
|
||||
// normally the kernel SHOULD not
|
||||
// arrive here.
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
#include <kernel/hardware/tmu.h>
|
||||
#include <kernel/vbr.h>
|
||||
|
||||
#include <lib/display.h>
|
||||
|
||||
void vhex_context_set(void)
|
||||
{
|
||||
extern uint32_t vhex_vbr;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <kernel/devices/display.h>
|
||||
#include <lib/display.h>
|
||||
#include <kernel/util.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
void display_ioctl(uint32_t cmd, ...)
|
||||
|
@ -35,12 +35,12 @@ void display_ioctl(uint32_t cmd, ...)
|
|||
}
|
||||
case DISPLAY_IOCTL_CLEAR:
|
||||
{
|
||||
dclear(); // <- remove me ?
|
||||
kvram_clear();
|
||||
break;
|
||||
}
|
||||
case DISPLAY_IOCTL_DISPLAY:
|
||||
{
|
||||
dupdate(); // <- remove me ?
|
||||
kvram_display();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#include <kernel/devices/tty.h>
|
||||
#include <kernel/devices/display.h>
|
||||
#include <kernel/devices/keyboard.h>
|
||||
#include <lib/display.h>
|
||||
#include <lib/string.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
// Internal TTY object.
|
||||
struct tty_s tty;
|
||||
|
|
|
@ -3,10 +3,7 @@
|
|||
#include <kernel/context.h>
|
||||
#include <kernel/atomic.h>
|
||||
#include <kernel/syscall.h>
|
||||
#include <lib/display.h>
|
||||
#include <lib/string.h>
|
||||
#include <lib/stdio.h>
|
||||
#include <lib/timer.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
// Intenral functions
|
||||
static void wait_keyboard_event(void);
|
||||
|
@ -340,8 +337,8 @@ static void cursor_callback(struct keyboard_obj_s *keyboard)
|
|||
tty_ioctl(TTY_IOCTL_GETDY, &y);
|
||||
|
||||
// Display cursor.
|
||||
dreverse(x, y, (KERNEL_FONT_REAL_WIDTH + 1), (KERNEL_FONT_REAL_HEIGHT + 1));
|
||||
dupdate();
|
||||
kvram_reverse(x, y, (KERNEL_FONT_REAL_WIDTH + 1), (KERNEL_FONT_REAL_HEIGHT + 1));
|
||||
kvram_display();
|
||||
|
||||
// Restore TTY cursor position
|
||||
tty.cursor.x = sttyx;
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#include <kernel/devices/tty.h>
|
||||
#include <kernel/devices/display.h>
|
||||
#include <kernel/atomic.h>
|
||||
#include <lib/display.h>
|
||||
#include <lib/string.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
// Internal TTY object.
|
||||
extern struct tty_s tty;
|
||||
|
|
|
@ -2,15 +2,13 @@
|
|||
#include <kernel/hardware/ubc.h>
|
||||
#include <kernel/hardware/power.h>
|
||||
#include <kernel/syscall.h>
|
||||
#include <kernel/dbr.h>
|
||||
#include <kernel/extra.h>
|
||||
#include <lib/display.h>
|
||||
#include <kernel/dbr.h>
|
||||
|
||||
// Internal data used by UBC device.
|
||||
void *casio_dbr;
|
||||
|
||||
// Internal function.
|
||||
extern void test(void);
|
||||
extern void ubc_handler_pre(void);
|
||||
|
||||
int ubc_open(void)
|
||||
|
@ -36,7 +34,7 @@ int ubc_open(void)
|
|||
SH7305_UBC.CBR0.CE = 0; // Disable Channel 0.
|
||||
|
||||
// Set up target address.
|
||||
SH7305_UBC.CAR0 = (uint32_t)&test; // Tested programe address !
|
||||
SH7305_UBC.CAR0 = 0x00000000; // Tested programe address !
|
||||
SH7305_UBC.CAMR0 = 0x00000000; // Address Mask.
|
||||
|
||||
// Setup Control register.
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
#include <kernel/fs/smem.h>
|
||||
#include <kernel/fs/file.h>
|
||||
|
||||
/* casio_smem_lseek() - File cursor management */
|
||||
off_t casio_smem_lseek(FILE *file, off_t offset, int whence)
|
||||
{
|
||||
// Check potential error.
|
||||
if (file == NULL)
|
||||
return (-1);
|
||||
|
||||
if (whence == SEEK_SET){
|
||||
file->cursor = offset;
|
||||
return (file->cursor);
|
||||
}
|
||||
if (whence == SEEK_CUR){
|
||||
file->cursor = file->cursor + offset;
|
||||
return (file->cursor);
|
||||
}
|
||||
if (whence == SEEK_END){
|
||||
file->cursor = file->size + offset - 1;
|
||||
return (file->cursor);
|
||||
}
|
||||
return (-1);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#include <kernel/fs/smem.h>
|
||||
|
||||
// Internal symbols
|
||||
casio_smem_header_t *casio_smem_header_table;
|
||||
casio_smem_block_t *casio_smem_block_table;
|
||||
uint16_t current_parent_id;
|
||||
|
||||
/* casio_smem_mount() - Get Block and Preheader Table addresses */
|
||||
int casio_smem_mount(void)
|
||||
{
|
||||
// Casio SMEM block table start always at 0xa0270000
|
||||
casio_smem_block_table = (void *)0xa0270000;
|
||||
//TODO: check block table intergrity.
|
||||
|
||||
// Casio SMEM preheader table start always at the end of the block table.
|
||||
// Normaly start at 0xa0270320 but not always (?)
|
||||
int i = -1;
|
||||
while (casio_smem_block_table[++i].magic_start == CASIO_SMEM_BLOCK_ENTRY_MAGIC);
|
||||
casio_smem_header_table = (void *)&casio_smem_block_table[i];
|
||||
|
||||
//TODO: check header intergrity !
|
||||
|
||||
current_parent_id = CASIO_SMEM_ROOT_ID;
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
#include <kernel/fs/smem.h>
|
||||
#include <kernel/fs/file.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
//FIXME: find better way to walk into fragment (use ID)
|
||||
static size_t casio_smem_get_file_size(casio_smem_header_t *file)
|
||||
{
|
||||
casio_smem_fragment_t *fragment;
|
||||
size_t count;
|
||||
|
||||
count = 0;
|
||||
fragment = (void *)((uint32_t)file + sizeof(casio_smem_header_t));
|
||||
while (fragment->magic == CASIO_SMEM_FRAGMENT_MAGIC)
|
||||
{
|
||||
count = count + fragment->data_size + 1;
|
||||
fragment = fragment + 1;
|
||||
}
|
||||
return (count);
|
||||
}
|
||||
|
||||
/* casio_smem_get_file() - Walk into the Casio's File System and search the target file */
|
||||
static casio_smem_header_t *casio_smem_get_file(char const *name, uint16_t *parent_id)
|
||||
{
|
||||
extern casio_smem_header_t *casio_smem_header_table;
|
||||
casio_smem_fragment_t *fragment;
|
||||
casio_smem_header_t *header;
|
||||
int i;
|
||||
|
||||
// Walk into Casio SMEM File System.
|
||||
header = casio_smem_header_table;
|
||||
while (header->info == CASIO_SMEM_HEADER_INFO_EXIST ||
|
||||
header->info == CASIO_SMEM_HEADER_INFO_DELETE)
|
||||
{
|
||||
// Check new file validity.
|
||||
if (header->info == CASIO_SMEM_HEADER_INFO_EXIST &&
|
||||
header->parent.id == *parent_id)
|
||||
{
|
||||
// Compare File name.
|
||||
i = -1;
|
||||
while (++i < 12 &&
|
||||
header->name[i] != 0x0000 &&
|
||||
header->name[i] != 0xffff &&
|
||||
(header->name[i] & 0x00ff) == name[i]);
|
||||
|
||||
// Check error.
|
||||
if (name[i] == '\0' &&
|
||||
(header->name[i] == 0x0000 ||
|
||||
header->name[i] == 0xffff))
|
||||
{
|
||||
*parent_id = header->id;
|
||||
return (header);
|
||||
}
|
||||
}
|
||||
|
||||
// We need to skip fragmented data
|
||||
fragment = (void *)((uint32_t)header + sizeof(casio_smem_header_t));
|
||||
if (fragment->magic == CASIO_SMEM_FRAGMENT_MAGIC)
|
||||
{
|
||||
// The fastest way to skip fragmented data
|
||||
fragment = (void *)((uint32_t)fragment +
|
||||
(sizeof(casio_smem_fragment_t) * fragment->frag_total));
|
||||
}
|
||||
|
||||
// Get next header.
|
||||
header = (void *)fragment;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* casio_smem_open() - Find target file and setup abstraction file structure */
|
||||
int casio_smem_open(FILE *file, char const *name, int mode)
|
||||
{
|
||||
extern uint16_t current_parent_id;
|
||||
casio_smem_header_t *file_raw;
|
||||
uint16_t parent_id;
|
||||
char file_name[14];
|
||||
int slot_number;
|
||||
int i;
|
||||
|
||||
// check error.
|
||||
if (mode != O_RDONLY || name == NULL)
|
||||
return (-1);
|
||||
|
||||
// Get parent ID.
|
||||
if (*name == '/')
|
||||
{
|
||||
parent_id = CASIO_SMEM_ROOT_ID;
|
||||
name += 1;
|
||||
} else {
|
||||
parent_id = current_parent_id;
|
||||
}
|
||||
|
||||
// File Systeme walk entry.
|
||||
while (*name != '\0')
|
||||
{
|
||||
// Get current file name.
|
||||
i = -1;
|
||||
while (name[++i] != '\0' && name[i] != '/' && i < 14)
|
||||
file_name[i] = name[i];
|
||||
|
||||
// Check file name validity.
|
||||
if (i >= 12 && name[i] != '\0' && name[i] != '/')
|
||||
return (-1);
|
||||
|
||||
// Update internal informations.
|
||||
file_name[i] = '\0';
|
||||
name = name + i;
|
||||
|
||||
// find the file.
|
||||
file_raw = casio_smem_get_file(file_name, &parent_id);
|
||||
if (file_raw == NULL)
|
||||
return (-1);
|
||||
|
||||
// Directory check
|
||||
if (name[0] == '/')
|
||||
{
|
||||
if (file_raw->type != CASIO_SMEM_HEADER_TYPE_DIRECTORY)
|
||||
return (-2);
|
||||
name = name + 1;
|
||||
}
|
||||
}
|
||||
|
||||
kvram_clear();
|
||||
kvram_print(0, 0, "CUL !");
|
||||
kvram_display();
|
||||
while (1);
|
||||
|
||||
// Initilaize fiel object
|
||||
// TODO: Use VFS to do this !!
|
||||
file->cursor = 0;
|
||||
file->mode = mode;
|
||||
file->abstract = file_raw;
|
||||
file->size = casio_smem_get_file_size(file_raw);
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
#include <kernel/fs/smem.h>
|
||||
#include <kernel/fs/file.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
/* casio_smem_data_base_address() - Generate the fragmented data address (0xa0000000 + offset) */
|
||||
static void *casio_smem_get_data_base_address(casio_smem_fragment_t *fragment)
|
||||
{
|
||||
extern casio_smem_block_t *casio_smem_block_table;
|
||||
casio_smem_block_t *block;
|
||||
|
||||
block = casio_smem_block_table;
|
||||
while (block->magic_start == CASIO_SMEM_BLOCK_ENTRY_MAGIC &&
|
||||
block->info.id != fragment->data_block_id)
|
||||
{
|
||||
block = block + 1;
|
||||
}
|
||||
if (block->info.id != fragment->data_block_id)
|
||||
return (NULL);
|
||||
return ((void *)(block->offset + fragment->data_offset));
|
||||
}
|
||||
|
||||
/* casio_smem_read() - Read the file data (based on internal cursor) */
|
||||
ssize_t casio_smem_read(FILE *file, void *buf, size_t count)
|
||||
{
|
||||
casio_smem_fragment_t *fragment;
|
||||
off_t fragment_data_offset;
|
||||
void *data_base_addr;
|
||||
ssize_t current_size;
|
||||
size_t real_size;
|
||||
|
||||
// Get Check obvious error.
|
||||
if (file == NULL || buf == NULL || file->cursor > (off_t)file->size)
|
||||
return (-1);
|
||||
|
||||
// Get the "real" reading size
|
||||
if (file->size - file->cursor < count)
|
||||
count = file->size - file->cursor;
|
||||
|
||||
// Get the current data fragment.
|
||||
current_size = 0;
|
||||
fragment = (void *)((uint32_t)file->abstract + sizeof(casio_smem_header_t));
|
||||
while (fragment->magic == CASIO_SMEM_FRAGMENT_MAGIC &&
|
||||
file->cursor > (off_t)(current_size + fragment->data_size + 1))
|
||||
{
|
||||
current_size = current_size + fragment->data_size + 1;
|
||||
fragment = fragment + 1;
|
||||
}
|
||||
fragment_data_offset = file->cursor - current_size;
|
||||
|
||||
// Read file data
|
||||
current_size = 0;
|
||||
while (current_size < (ssize_t)count &&
|
||||
fragment->magic == CASIO_SMEM_FRAGMENT_MAGIC)
|
||||
{
|
||||
// Calculate the real size to read.
|
||||
real_size = fragment->data_size + 1 - fragment_data_offset;
|
||||
if (real_size >= count - current_size)
|
||||
real_size = count - current_size;
|
||||
|
||||
// Get the data address.
|
||||
data_base_addr = casio_smem_get_data_base_address(fragment);
|
||||
if (data_base_addr == NULL)
|
||||
return (current_size);
|
||||
|
||||
// Handle fragment data offset.
|
||||
if (fragment_data_offset != 0){
|
||||
data_base_addr = (void *)(((uint32_t)data_base_addr) + fragment_data_offset);
|
||||
fragment_data_offset = 0;
|
||||
}
|
||||
|
||||
// Fill the buffer
|
||||
memcpy((void*)(buf + current_size), (void*)(0xa0000000 + data_base_addr), real_size);
|
||||
|
||||
// Update informations.
|
||||
current_size = current_size + real_size;
|
||||
file->cursor = file->cursor + real_size;
|
||||
fragment = fragment + 1;
|
||||
}
|
||||
((uint8_t*)buf)[current_size] = '\0';
|
||||
return (current_size);
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
#include <kernel/hardware/keysc.h>
|
||||
#include <kernel/hardware/intc.h>
|
||||
#include <lib/display.h>
|
||||
|
||||
// Internal functions
|
||||
extern void keycache_update(int row, int column, uint8_t key_frame);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include <kernel/hardware/tmu.h>
|
||||
#include <kernel/devices/timer.h>
|
||||
#include <lib/display.h>
|
||||
|
||||
// Internal timer "cache".
|
||||
struct timer_cache_s timercache[TIMER_NUMBER];
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include <kernel/keybios.h>
|
||||
#include <kernel/syscall.h>
|
||||
#include <kernel/extra.h>
|
||||
#include <lib/display.h>
|
||||
|
||||
|
||||
// Internal function.
|
||||
|
@ -23,7 +22,7 @@ void ubc_module_handler(int action)
|
|||
|
||||
void ubc_handler(struct ubc_context_s *context, int channel)
|
||||
{
|
||||
void (*menu)(ubc_session_t *session);
|
||||
/* void (*menu)(ubc_session_t *session);
|
||||
ubc_session_t session;
|
||||
|
||||
// Initialize new session.
|
||||
|
@ -47,12 +46,12 @@ void ubc_handler(struct ubc_context_s *context, int channel)
|
|||
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; // 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,120 +0,0 @@
|
|||
#include <kernel/devices/ubc.h>
|
||||
#include <kernel/devices/display.h>
|
||||
#include <kernel/hardware/ubc.h>
|
||||
#include <kernel/keybios.h>
|
||||
#include <lib/display.h>
|
||||
|
||||
// Menu string format.
|
||||
const char *content_string[] = {
|
||||
"!!!! UBC INTERRUPT !!!!",
|
||||
"Special registers:",
|
||||
"SPC = %p",
|
||||
"Stack = %p",
|
||||
"SSR = %#x",
|
||||
"\n",
|
||||
"Generale registers:",
|
||||
"r0 = %#x",
|
||||
"r1 = %#x",
|
||||
"r2 = %#x",
|
||||
"r3 = %#x",
|
||||
"r4 = %#x",
|
||||
"r5 = %#x",
|
||||
"r6 = %#x",
|
||||
"r7 = %#x",
|
||||
"r8 = %#x",
|
||||
"r9 = %#x",
|
||||
"r10 = %#x",
|
||||
"r11 = %#x",
|
||||
"r12 = %#x",
|
||||
"r13 = %#x",
|
||||
"r14 = %#x",
|
||||
"r15 = %#x",
|
||||
"\n",
|
||||
"Debug informations:",
|
||||
"context = %p",
|
||||
"UBC interrupt = %#x",
|
||||
"Channel = %#x",
|
||||
NULL
|
||||
};
|
||||
|
||||
//
|
||||
// cursor_update - Update cursor position key pressed based.
|
||||
// @note:
|
||||
// Some limits are hard coded so be careful.
|
||||
//
|
||||
static void cursor_update(ubc_session_t *session)
|
||||
{
|
||||
if (session->key == KEY_CTRL_UP &&
|
||||
session->menu.context.cursor > 0)
|
||||
{
|
||||
session->menu.context.cursor = session->menu.context.cursor - 1;
|
||||
return;
|
||||
}
|
||||
if (session->key == KEY_CTRL_DOWN &&
|
||||
session->menu.context.cursor < 28 - DISPLAY_VCHAR_MAX)
|
||||
{
|
||||
session->menu.context.cursor = session->menu.context.cursor + 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// menu_context - Show programe context.
|
||||
// @note:
|
||||
// This is not the best way to do the job,
|
||||
// but for now the goal is the create a fonctionnal
|
||||
// on-calc debugger.
|
||||
//
|
||||
void menu_context(ubc_session_t *session)
|
||||
{
|
||||
// Menu string data
|
||||
uint32_t content_data[] = {
|
||||
0,
|
||||
0,
|
||||
session->context->spc,
|
||||
session->context->reg[15],
|
||||
session->context->ssr,
|
||||
0,
|
||||
0,
|
||||
session->context->reg[0],
|
||||
session->context->reg[1],
|
||||
session->context->reg[2],
|
||||
session->context->reg[3],
|
||||
session->context->reg[4],
|
||||
session->context->reg[5],
|
||||
session->context->reg[6],
|
||||
session->context->reg[7],
|
||||
session->context->reg[8],
|
||||
session->context->reg[9],
|
||||
session->context->reg[10],
|
||||
session->context->reg[11],
|
||||
session->context->reg[12],
|
||||
session->context->reg[13],
|
||||
session->context->reg[14],
|
||||
session->context->reg[15],
|
||||
0,
|
||||
0,
|
||||
(uint32_t)session->context,
|
||||
SH7305_UBC.CCMFR.LONG_WORD,
|
||||
session->channel
|
||||
};
|
||||
|
||||
// Update cursor position.
|
||||
cursor_update(session);
|
||||
|
||||
// Clear VRAM.
|
||||
dclear();
|
||||
|
||||
// Display menu based on cursor position.
|
||||
for (int i = 0 ; content_string[i + session->menu.context.cursor] != NULL &&
|
||||
i < DISPLAY_VCHAR_MAX ; i = i + 1)
|
||||
{
|
||||
dprint(0, i,
|
||||
content_string[i + session->menu.context.cursor],
|
||||
content_data[i + session->menu.context.cursor]
|
||||
);
|
||||
}
|
||||
|
||||
// Display VRAM
|
||||
dupdate();
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
#include <kernel/devices/ubc.h>
|
||||
#include <kernel/devices/display.h>
|
||||
#include <kernel/opcode.h>
|
||||
#include <kernel/keybios.h>
|
||||
#include <lib/display.h>
|
||||
#include <lib/stdio.h>
|
||||
|
||||
static uint32_t get_arg(uint16_t code, const struct opcode_s *opcode, int id)
|
||||
{
|
||||
int shift;
|
||||
|
||||
// Check arg mask
|
||||
if (opcode->arg_mask[id] == 0x0000)
|
||||
return (0);
|
||||
|
||||
// Get arg shift.
|
||||
shift = -1;
|
||||
while (++shift < 16 && !(opcode->arg_mask[id] & (0x01 << shift)));
|
||||
|
||||
// Get argument.
|
||||
return ((code & opcode->arg_mask[id]) >> shift);
|
||||
}
|
||||
|
||||
static void display_mnemonic(ubc_session_t *session)
|
||||
{
|
||||
char line[128];
|
||||
uint16_t *area;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
// Get starting area.
|
||||
// TODO: update me !!
|
||||
area = (void *)(session->context->spc + (session->menu.disassembly.vcursor << 1));
|
||||
|
||||
// Main Loop.
|
||||
i = -1;
|
||||
while (++i < DISPLAY_VCHAR_MAX)
|
||||
{
|
||||
// Generate first part.
|
||||
sprintf(line, "%8x %4x ", &area[i], area[i]);
|
||||
|
||||
// Try to find opcode.
|
||||
j = -1;
|
||||
while (opcode_list[++j].name != NULL)
|
||||
{
|
||||
// Check opcode.
|
||||
if ((area[i] & opcode_list[j].mask) != opcode_list[j].code)
|
||||
continue;
|
||||
|
||||
// Generate line via special function.
|
||||
if (opcode_list[j].special != NULL)
|
||||
{
|
||||
opcode_list[j].special(&line[14], &area[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
// Generate common line.
|
||||
sprintf(&line[14],
|
||||
opcode_list[j].name,
|
||||
get_arg(area[i], &opcode_list[j], 0),
|
||||
get_arg(area[i], &opcode_list[j], 1),
|
||||
get_arg(area[i], &opcode_list[j], 2)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
// If no opcode are found, generate "empty" line.
|
||||
if (opcode_list[j].name == NULL)
|
||||
sprintf(&line[14], ".word 0x%4x", area[i]);
|
||||
|
||||
// Display line !
|
||||
dprint(session->menu.disassembly.hcursor, i, line);
|
||||
|
||||
// Highlight break line if needed.
|
||||
if ((uint32_t)&area[i] == session->context->spc)
|
||||
{
|
||||
dreverse(
|
||||
0,
|
||||
i * (KERNEL_FONT_REAL_HEIGHT + 1),
|
||||
DISPLAY_SCREEN_WIDTH,
|
||||
KERNEL_FONT_REAL_HEIGHT + 1
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cursor_update(ubc_session_t *session)
|
||||
{
|
||||
// Horizontal update.
|
||||
if (session->key == KEY_CTRL_LEFT)
|
||||
session->menu.disassembly.hcursor += 1;
|
||||
if (session->key == KEY_CTRL_RIGHT)
|
||||
session->menu.disassembly.hcursor -= 1;
|
||||
|
||||
// Vertical update.
|
||||
if (session->key == KEY_CTRL_UP)
|
||||
session->menu.disassembly.vcursor -= 1;
|
||||
if (session->key == KEY_CTRL_DOWN)
|
||||
session->menu.disassembly.vcursor += 1;
|
||||
}
|
||||
|
||||
void menu_disassembly(ubc_session_t *session)
|
||||
{
|
||||
// Update cursor position.
|
||||
cursor_update(session);
|
||||
|
||||
// display ASM.
|
||||
dclear();
|
||||
display_mnemonic(session);
|
||||
dupdate();
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
#include <lib/display.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
void exception_handler(void)
|
||||
{
|
||||
|
@ -18,8 +18,8 @@ void exception_handler(void)
|
|||
);
|
||||
|
||||
// Write exception informations.
|
||||
dclear();
|
||||
dprint(0, 0,
|
||||
kvram_clear();
|
||||
kvram_print(0, 0,
|
||||
"Ho crap ! Exception !\n"
|
||||
"tra: %#x\n"
|
||||
"expevt: %#x\n"
|
||||
|
@ -32,6 +32,6 @@ void exception_handler(void)
|
|||
ssr,
|
||||
sr
|
||||
);
|
||||
dupdate();
|
||||
kvram_display();
|
||||
while (1);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <lib/display.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
// Handler prototype.
|
||||
extern void keysc_handler(void);
|
||||
|
@ -25,13 +25,13 @@ void interrupt_handler(void)
|
|||
}
|
||||
|
||||
// Display error.
|
||||
dclear();
|
||||
dprint(0, 0,
|
||||
kvram_clear();
|
||||
kvram_print(0, 0,
|
||||
"Ho crap ! Interrupt error !\n"
|
||||
"Interrupt ID (%#x)\n"
|
||||
"Error: handler not foud !\n",
|
||||
intevt
|
||||
);
|
||||
dupdate();
|
||||
kvram_display();
|
||||
while (1);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include <lib/display.h>
|
||||
#include <kernel/syscall.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
__attribute__((section(".vhex.tlb"), interrupt_handler))
|
||||
void tlb_handler(void)
|
||||
|
@ -20,8 +19,8 @@ void tlb_handler(void)
|
|||
);
|
||||
|
||||
// Write exception informations.
|
||||
dclear();
|
||||
dprint(0, 0,
|
||||
kvram_clear();
|
||||
kvram_print(0, 0,
|
||||
"Ho crap ! TLB Exception !\n"
|
||||
"tra: %#x\n"
|
||||
"expevt: %#x\n"
|
||||
|
@ -34,6 +33,6 @@ void tlb_handler(void)
|
|||
ssr,
|
||||
sr
|
||||
);
|
||||
dupdate();
|
||||
kvram_display();
|
||||
while (1);
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1,24 @@
|
|||
#include <kernel/loader.h>
|
||||
#include <kernel/fs/smem.h>
|
||||
#include <kernel/fs/file.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
void *loader(const char *path)
|
||||
{
|
||||
FILE file;
|
||||
|
||||
// TODO: use VFS !
|
||||
if (casio_smem_open(&file, path, O_RDONLY) != 0)
|
||||
return (NULL);
|
||||
|
||||
kvram_clear();
|
||||
kvram_print(0, 0, "File found !!");
|
||||
kvram_print(0, 1, "inode = %p", file.abstract);
|
||||
kvram_print(0, 2, "path = %s", path);
|
||||
kvram_display();
|
||||
while (1);
|
||||
|
||||
// TODO: detect format !!
|
||||
//return (loader_elf(file));
|
||||
return (NULL);
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
#include <kernel/memory.h>
|
||||
#include <lib/display.h>
|
||||
|
||||
// Internal data.
|
||||
struct memory_info_s pmemory;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include <kernel/process.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
// This function SHOULD not be called
|
||||
// without atomic operation !!
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include <kernel/process.h>
|
||||
#include <lib/string.h>
|
||||
#include <kernel/unistd_32.h>
|
||||
#include <kernel/memory.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
pid_t process_create(const char *name)
|
||||
{
|
||||
|
@ -16,18 +18,44 @@ pid_t process_create(const char *name)
|
|||
if (process == NULL)
|
||||
return (-1);
|
||||
|
||||
// Initialize stack
|
||||
process->context.reg[15] = (uint32_t)pm_alloc(PROCESS_STACK_SIZE);
|
||||
if (process->context.reg[15] == 0x00000000)
|
||||
{
|
||||
//TODO: errno
|
||||
//FIXME: free allocated process.
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// Set process name.
|
||||
strncpy(process->name, name, PROCESS_NAME_LENGHT);
|
||||
|
||||
// Initialize context.
|
||||
for (int i = 0 ; i < 16 ; i = i + 1)
|
||||
for (int i = 0 ; i < 15 ; i = i + 1)
|
||||
process->context.reg[i] = 0x00000000;
|
||||
|
||||
// Initialize "special" registers.
|
||||
process->context.gbr = 0x00000000;
|
||||
process->context.macl = 0x00000000;
|
||||
process->context.mach = 0x00000000;
|
||||
process->context.ssr = 0x00000000;
|
||||
process->context.spc = 0x00000000;
|
||||
|
||||
// initialize "exit" part.
|
||||
uint8_t callexit[6] = {
|
||||
0b11000011, __NR_exit, // trapa #__NR_exit
|
||||
0b10110000, 0b00000100, // bsr PC + 2 - 4
|
||||
0b00000000, 0b00001001 // nop
|
||||
};
|
||||
process->context.pr = (uint32_t)pm_alloc(6);
|
||||
if (process->context.pr == 0x00000000)
|
||||
{
|
||||
//TODO: errno
|
||||
//FIXME: free allocated process.
|
||||
return (-1);
|
||||
}
|
||||
memcpy((void *)process->context.pr, callexit, 6);
|
||||
|
||||
// Initialize processes.
|
||||
process->parent = process_current;
|
||||
process->child = NULL;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include <kernel/syscall.h>
|
||||
#include <lib/display.h>
|
||||
|
||||
static const void *sys_handler[] = {
|
||||
NULL, //restart
|
||||
|
|
|
@ -0,0 +1,265 @@
|
|||
#include <kernel/util.h>
|
||||
#include <kernel/atomic.h>
|
||||
#include <kernel/devices/display.h>
|
||||
#include <stdarg.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_end();
|
||||
}
|
||||
|
||||
/* kvram_display() - Disaplay Video RAM into screen */
|
||||
void kvram_display(void)
|
||||
{
|
||||
//TODO: handle screen hadware !
|
||||
t6k11_display(vram);
|
||||
}
|
||||
|
||||
/* kvram_scroll() - Scroll up the Video RAM */
|
||||
void kvram_scroll(int lines)
|
||||
{
|
||||
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_end();
|
||||
}
|
||||
|
||||
/* kvram_reverse() - Reverse Video RAM area */
|
||||
void kvram_reverse(int x, int y, int width, int height)
|
||||
{
|
||||
int vram_offset_y;
|
||||
int j;
|
||||
|
||||
// Check error.
|
||||
if (width < 0 || height < 0)
|
||||
return;
|
||||
|
||||
// Get "real" X position and area width.
|
||||
if (x < 0)
|
||||
{
|
||||
width = width + x;
|
||||
x = 0;
|
||||
} else {
|
||||
if (x + width >= DISPLAY_SCREEN_WIDTH)
|
||||
width = DISPLAY_SCREEN_WIDTH - x;
|
||||
}
|
||||
|
||||
// Get "real" Y position and area height.
|
||||
if (y < 0)
|
||||
{
|
||||
height = height + x;
|
||||
y = 0;
|
||||
} else {
|
||||
if (y + height >= DISPLAY_SCREEN_HEIGHT)
|
||||
height = DISPLAY_SCREEN_HEIGHT - x;
|
||||
}
|
||||
|
||||
// Check potential error.
|
||||
// @note we do not check height because the while()
|
||||
// while do the job for us.
|
||||
if (width < 0)
|
||||
return;
|
||||
|
||||
// Generate VRAM offset for Y axis.
|
||||
// @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 = (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);
|
||||
}
|
||||
vram_offset_y = vram_offset_y - 4;
|
||||
}
|
||||
|
||||
// End of atomic operation
|
||||
atomic_end();
|
||||
}
|
||||
|
||||
/* kvram_print() - Print formated string on Video RAM */
|
||||
void kvram_print(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;
|
||||
|
||||
// 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)
|
||||
{
|
||||
font_draw(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')
|
||||
{
|
||||
font_draw(x, y, '@');
|
||||
x = x + KERNEL_FONT_REAL_WIDTH + 1;
|
||||
}
|
||||
|
||||
// Add "0x"
|
||||
font_draw(x, y, '0');
|
||||
x = x + KERNEL_FONT_REAL_WIDTH + 1;
|
||||
font_draw(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)
|
||||
{
|
||||
font_draw(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')
|
||||
{
|
||||
font_draw(x, y, ((char*)nb)[digits++]);
|
||||
x = x + KERNEL_FONT_REAL_WIDTH + 1;
|
||||
}
|
||||
i = i + 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Default, display character
|
||||
font_draw(x, y, str[i]);
|
||||
x = x + KERNEL_FONT_REAL_WIDTH + 1;
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/* kvram_ascii() - Draw ASCII character into Video RAM */
|
||||
void kvram_ascii(int x, int y, char const c)
|
||||
{
|
||||
font_draw(x, y, c);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#include <kernel/util.h>
|
||||
|
||||
//TODO: update me :(
|
||||
void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
while ((int)--n >= 0)
|
||||
((uint8_t*)s)[n] = c;
|
||||
return (s);
|
||||
}
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
// TODO: update me :(
|
||||
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);
|
||||
}
|
||||
|
||||
// TODO: update me :(
|
||||
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);
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
#include <lib/timer.h>
|
||||
#include <kernel/util.h>
|
||||
#include <kernel/hardware/tmu.h>
|
||||
#include <kernel/devices/timer.h>
|
||||
#include <kernel/atomic.h>
|
||||
#include <lib/display.h>
|
||||
|
||||
//TODO: update !
|
||||
int timer_install(void *callback, void *arg, uint32_t delay_ms, uint8_t mode)
|
||||
{
|
||||
extern struct timer_cache_s timercache[TIMER_NUMBER];
|
||||
|
@ -47,3 +47,32 @@ int timer_install(void *callback, void *arg, uint32_t delay_ms, uint8_t mode)
|
|||
atomic_end();
|
||||
return (timer_ID);
|
||||
}
|
||||
|
||||
//TODO: update !
|
||||
int timer_uninstall(int timer_ID)
|
||||
{
|
||||
extern struct timer_cache_s timercache[TIMER_NUMBER];
|
||||
|
||||
// Check bad ID
|
||||
if (timer_ID < 0 || timer_ID >= TIMER_NUMBER)
|
||||
return (-1);
|
||||
|
||||
// Start Atomic operation.
|
||||
atomic_start();
|
||||
|
||||
// Stop Hardware timer.
|
||||
SH7305_TMU.TSTR.BYTE &= ~(1 << timer_ID);
|
||||
|
||||
// Uninit hardware timer.
|
||||
SH7305_TMU.TIMER[timer_ID].TCR.UNF = 0; // Clear interrupt flag.
|
||||
SH7305_TMU.TIMER[timer_ID].TCR.UNIE = 0; // Disable interrupt.
|
||||
SH7305_TMU.TIMER[timer_ID].TCOR = 0xffffffff;
|
||||
SH7305_TMU.TIMER[timer_ID].TCNT = 0xffffffff;
|
||||
|
||||
// Free'd timer cache.
|
||||
timercache[timer_ID].status = TIMER_UNUSED;
|
||||
|
||||
// Stop atomic operation and return.
|
||||
atomic_end();
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
#!/usr/bin/make -f
|
||||
# ---
|
||||
# Project: Vhex - Librairies part.
|
||||
# Author: yann.magnin@epitech.eu
|
||||
# ---
|
||||
include ../../global.mk
|
||||
|
||||
|
||||
|
||||
|
||||
#------- --------#
|
||||
# Generic variables #
|
||||
#------- --------#
|
||||
HEADER := -I../../include
|
||||
BUILD := ../../build/lib/
|
||||
TARGET-MODULES := stdio string unistd display
|
||||
|
||||
|
||||
|
||||
|
||||
#------- --------#
|
||||
# Automated variables #
|
||||
#------- --------#
|
||||
$(foreach mod,$(TARGET-MODULES),$(eval \
|
||||
target-$(mod)-src := $$(wildcard $(mod)/*.c) $n\
|
||||
target-$(mod)-src += $$(wildcard $(mod)/*.s) $n\
|
||||
target-$(mod)-src += $$(wildcard $(mod)/*.S) $n\
|
||||
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))
|
||||
|
||||
|
||||
|
||||
|
||||
#------- --------#
|
||||
# Generic rules #
|
||||
#------- --------#
|
||||
all: | $(BUILD) $(TARGET-LIBS)
|
||||
|
||||
$(BUILD):
|
||||
@ printf "Create $(blue)$@$(nocolor) directory\n"
|
||||
@ mkdir -p $@
|
||||
|
||||
debug:
|
||||
@ echo 'lib: $(TARGET-LIBS)'
|
||||
@ echo 'src: $(target-stdio-src)'
|
||||
@ echo 'obj: $(target-stdio-obj)'
|
||||
@ echo 'directory: $(TARGET-MODULES)'
|
||||
@ echo 'debug: $(BUILD)'
|
||||
|
||||
|
||||
|
||||
|
||||
#------- --------#
|
||||
# Rule functions #
|
||||
#------- --------#
|
||||
define rule-src
|
||||
$(patsubst %,$(BUILD)%.o,$(subst /,_,$(basename $1))): $1
|
||||
@ printf "compiling $(white)$$<$(nocolor)..."
|
||||
@ $(CC) $(CFLAGS) -c $$< -o $$@ $(HEADER)
|
||||
@ printf "$(green)[ok]$(nocolor)\n"
|
||||
endef
|
||||
define rule-link
|
||||
$(patsubst %,lib_%.a,$1): $2
|
||||
@ printf "Link $(green)$$@$(nocolor) lib\n"
|
||||
$(AR) crs $$@ $$^
|
||||
endef
|
||||
|
||||
|
||||
|
||||
|
||||
#------- --------#
|
||||
# Automated rules #
|
||||
#------- --------#
|
||||
$(foreach mod,$(TARGET-MODULES), \
|
||||
$(foreach source,$(target-$(mod)-src), \
|
||||
$(eval $(call rule-src,$(source),$(mod)))) \
|
||||
$(eval $(call rule-link,$(mod),$(target-$(mod)-obj))) \
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
#------- --------#
|
||||
# Clean rules #
|
||||
#------- --------#
|
||||
clean:
|
||||
rm -rf $(BUILD)
|
||||
|
||||
fclean: clean
|
||||
rm -f $(TARGET-LIBS)
|
||||
|
||||
re: fclean all
|
||||
|
||||
|
||||
|
||||
|
||||
.PHONY: re clean fclean all debug
|
|
@ -0,0 +1,12 @@
|
|||
.text
|
||||
.global _dascii
|
||||
.type _dascii, @function
|
||||
|
||||
#include "kernel/unistd_32.h"
|
||||
|
||||
.align 2
|
||||
_dascii:
|
||||
trapa #__NR_kvram_ascii
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,8 +0,0 @@
|
|||
#include <lib/display.h>
|
||||
#include <kernel/font.h>
|
||||
|
||||
|
||||
void dascii(int x, int y, char const c)
|
||||
{
|
||||
font_draw(x, y, c);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
.text
|
||||
.global _dclear
|
||||
.type _dclear, @function
|
||||
|
||||
#include "kernel/unistd_32.h"
|
||||
|
||||
.align 2
|
||||
_dclear:
|
||||
trapa #__NR_kvram_clear
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,13 +0,0 @@
|
|||
#include <lib/display.h>
|
||||
|
||||
// Internal VRAM address.
|
||||
uint32_t vram[256];
|
||||
|
||||
void dclear(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 256;
|
||||
while (--i >= 0)
|
||||
vram[i] = 0x00000000;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
.text
|
||||
.global _dprint
|
||||
.type _dprint, @function
|
||||
|
||||
#include "kernel/unistd_32.h"
|
||||
|
||||
.align 2
|
||||
_dprint:
|
||||
trapa #__NR_kvram_print
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,42 +0,0 @@
|
|||
#include <lib/display.h>
|
||||
#include <kernel/devices/display.h>
|
||||
#include <lib/stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
void dprint(int x, int y, char const *str, ...)
|
||||
{
|
||||
char buffer[512];
|
||||
int default_pos_x;
|
||||
int starting_x;
|
||||
va_list ap;
|
||||
int i;
|
||||
|
||||
// printf string manipulation.
|
||||
// TODO: remove me !
|
||||
va_start(ap, str);
|
||||
vsprintf(buffer, str, ap);
|
||||
va_end(ap);
|
||||
|
||||
i = -1;
|
||||
starting_x = x;
|
||||
x = x * (KERNEL_FONT_REAL_WIDTH + 1);
|
||||
y = y * (KERNEL_FONT_REAL_HEIGHT + 1);
|
||||
default_pos_x = x;
|
||||
while (buffer[++i] != '\0')
|
||||
{
|
||||
if (buffer[i] == '\n')
|
||||
{
|
||||
y = y + KERNEL_FONT_REAL_HEIGHT + 1;
|
||||
x = default_pos_x;
|
||||
continue;
|
||||
}
|
||||
if (buffer[i] == '\t')
|
||||
{
|
||||
x = x / (KERNEL_FONT_REAL_WIDTH + 1);
|
||||
x = (x + (4 - ((x - starting_x) & 3))) * (KERNEL_FONT_REAL_WIDTH + 1);
|
||||
continue;
|
||||
}
|
||||
font_draw(x, y, buffer[i]);
|
||||
x = x + KERNEL_FONT_REAL_WIDTH + 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
.text
|
||||
.global _dreverse
|
||||
.type _dreverse, @function
|
||||
|
||||
#include "kernel/unistd_32.h"
|
||||
|
||||
.align 2
|
||||
_dreverse:
|
||||
trapa #__NR_kvram_reverse
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,57 +0,0 @@
|
|||
#include <lib/display.h>
|
||||
#include <kernel/devices/display.h>
|
||||
|
||||
void dreverse(int x, int y, int width, int height)
|
||||
{
|
||||
int vram_offset_y;
|
||||
int j;
|
||||
|
||||
// Check error.
|
||||
if (width < 0 || height < 0)
|
||||
return;
|
||||
|
||||
// Get "real" X position and area width.
|
||||
if (x < 0)
|
||||
{
|
||||
width = width + x;
|
||||
x = 0;
|
||||
} else {
|
||||
if (x + width >= DISPLAY_SCREEN_WIDTH)
|
||||
width = DISPLAY_SCREEN_WIDTH - x;
|
||||
}
|
||||
|
||||
// Get "real" Y position and area height.
|
||||
if (y < 0)
|
||||
{
|
||||
height = height + x;
|
||||
y = 0;
|
||||
} else {
|
||||
if (y + height >= DISPLAY_SCREEN_HEIGHT)
|
||||
height = DISPLAY_SCREEN_HEIGHT - x;
|
||||
}
|
||||
|
||||
// Check potential error.
|
||||
// @note we do not check height because the while()
|
||||
// while do the job for us.
|
||||
if (width < 0)
|
||||
return;
|
||||
|
||||
// Generate VRAM offset for Y axis.
|
||||
// @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 = (y + height - 1) << 2;
|
||||
|
||||
while (--height >= 0)
|
||||
{
|
||||
j = width + x;
|
||||
while (--j >= x)
|
||||
{
|
||||
vram[(j >> 5) + vram_offset_y] ^= 0x80000000 >> (j & 31);
|
||||
}
|
||||
vram_offset_y = vram_offset_y - 4;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
.text
|
||||
.global _dscroll
|
||||
.type _dscroll, @function
|
||||
|
||||
#include "kernel/unistd_32.h"
|
||||
|
||||
.align 2
|
||||
_dclear:
|
||||
trapa #__NR_kvram_scroll
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,27 +0,0 @@
|
|||
#include <lib/display.h>
|
||||
#include <kernel/devices/display.h>
|
||||
|
||||
void dscroll(int lines)
|
||||
{
|
||||
int i;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
.text
|
||||
.global _dupdate
|
||||
.type _dupdate, @function
|
||||
|
||||
#include "kernel/unistd_32.h"
|
||||
|
||||
.align 2
|
||||
_dupdate:
|
||||
trapa #__NR_kvram_display
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,8 +0,0 @@
|
|||
#include <lib/display.h>
|
||||
#include <kernel/devices/display.h>
|
||||
#include <kernel/hardware/t6k11.h>
|
||||
|
||||
void dupdate(void)
|
||||
{
|
||||
t6k11_display(vram);
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
#include <lib/timer.h>
|
||||
#include <kernel/hardware/tmu.h>
|
||||
#include <kernel/devices/timer.h>
|
||||
#include <kernel/atomic.h>
|
||||
|
||||
|
||||
int timer_uninstall(int timer_ID)
|
||||
{
|
||||
extern struct timer_cache_s timercache[TIMER_NUMBER];
|
||||
|
||||
// Check bad ID
|
||||
if (timer_ID < 0 || timer_ID >= TIMER_NUMBER)
|
||||
return (-1);
|
||||
|
||||
// Start Atomic operation.
|
||||
atomic_start();
|
||||
|
||||
// Stop Hardware timer.
|
||||
SH7305_TMU.TSTR.BYTE &= ~(1 << timer_ID);
|
||||
|
||||
// Uninit hardware timer.
|
||||
SH7305_TMU.TIMER[timer_ID].TCR.UNF = 0; // Clear interrupt flag.
|
||||
SH7305_TMU.TIMER[timer_ID].TCR.UNIE = 0; // Disable interrupt.
|
||||
SH7305_TMU.TIMER[timer_ID].TCOR = 0xffffffff;
|
||||
SH7305_TMU.TIMER[timer_ID].TCNT = 0xffffffff;
|
||||
|
||||
// Free'd timer cache.
|
||||
timercache[timer_ID].status = TIMER_UNUSED;
|
||||
|
||||
// Stop atomic operation and return.
|
||||
atomic_end();
|
||||
return (0);
|
||||
}
|
|
@ -6,7 +6,8 @@
|
|||
|
||||
.align 2
|
||||
_fork:
|
||||
trapa #__NR_fork
|
||||
!trapa #__NR_fork
|
||||
mov #-1, r0
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
#!/usr/bin/make -f
|
||||
## ---
|
||||
## Project: Vhex - On-calc debugger
|
||||
## Author: yann.magnin@epitech.eu
|
||||
## ---
|
||||
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
|
||||
DEBUG := ../../debug
|
||||
OUTPUT := ../../output
|
||||
|
||||
NAME := shell
|
||||
EXEC := $(OUTPUT)/$(NAME).elf
|
||||
LDFLAG := -T $(NAME).ld
|
||||
MEMORY_MAP := $(DEBUG)/$(NAME).map
|
||||
|
||||
|
||||
|
||||
|
||||
##---
|
||||
## Automated variables
|
||||
##---
|
||||
SRC :=
|
||||
DIRECTORY := $(shell find shell -not -path "*/\.*" -type d)
|
||||
# Get all source files
|
||||
$(foreach path,$(DIRECTORY),$(eval \
|
||||
SRC += $(wildcard $(path)/*.c) \
|
||||
$(wildcard $(path)/*.S) \
|
||||
$(wildcard $(path)/*.s) \
|
||||
))
|
||||
# Geneate all object files
|
||||
OBJ := $(patsubst %,$(BUILD)/%.o,$(subst /,_,$(subst src/,,$(basename $(SRC)))))
|
||||
|
||||
|
||||
|
||||
|
||||
##---
|
||||
## General rules
|
||||
##---
|
||||
all: | $(BUILD) $(DEBUG) $(EXEC)
|
||||
|
||||
$(EXEC): $(OBJ)
|
||||
$(CC) -Wl,-M $(LDFLAG) $(CFLAGS) -o $(DEBUG)/$(NAME).elf.big $(OBJ) $(HEADER) $(LIBS) -lgcc > $(MEMORY_MAP)
|
||||
$(OBJCOPY) -S $(DEBUG)/$(NAME).elf.big $@
|
||||
rm -f $(DEBUG)/$(NAME).elf.big
|
||||
|
||||
$(BUILD) $(DEBUG):
|
||||
@ printf "Create $(blue)$@$(nocolor) directory\n"
|
||||
@ mkdir -p $@
|
||||
|
||||
install: $(EXEC)
|
||||
sudo p7 send --force -d VHEX $^
|
||||
|
||||
check:
|
||||
@ echo 'src: $(SRC)'
|
||||
@ echo 'obj: $(OBJ)'
|
||||
@ echo 'directory: $(DIRECTORY)'
|
||||
|
||||
asm:
|
||||
@ $(OBJDUMP) -D $(DEBUG)/$(NAME).elf | less
|
||||
|
||||
map:
|
||||
@ cat $(MEMORY_MAP) | less
|
||||
|
||||
sec:
|
||||
@ $(OBJDUMP) -h $(DEBUG)/$(NAME).elf
|
||||
|
||||
|
||||
##---
|
||||
## Automated rules
|
||||
##---
|
||||
define rule-src
|
||||
$(patsubst %,$(BUILD)/%.o,$(subst /,_,$(subst src/,,$(basename $1)))): $1
|
||||
@ printf "compiling $(white)$$<$(nocolor)..."
|
||||
@ $(CC) $(CFLAGS) -o $$@ -c $$< $(HEADER) -lgcc
|
||||
@ printf "$(green)[ok]$(nocolor)\n"
|
||||
endef
|
||||
|
||||
$(foreach source,$(SRC),$(eval \
|
||||
$(call rule-src,$(source))) \
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
##---
|
||||
## Cleaning rules
|
||||
##---
|
||||
clean:
|
||||
rm -rf $(BUILD)
|
||||
rm -rf $(DEBUG)
|
||||
|
||||
fclean: clean
|
||||
rm -f $(EXEC)
|
||||
|
||||
re: fclean all
|
||||
|
||||
|
||||
|
||||
|
||||
.PHONY: re fclean clean all install
|
|
@ -0,0 +1,42 @@
|
|||
OUTPUT_ARCH(sh3)
|
||||
OUTPUT_FORMAT(elf32-sh)
|
||||
ENTRY(_main)
|
||||
|
||||
/*
|
||||
** Linker script for user executables.
|
||||
*/
|
||||
MEMORY
|
||||
{
|
||||
/* virtual memory, read-write segment */
|
||||
userram (WX) : o = 0x00000000, l = 256k
|
||||
}
|
||||
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD ;
|
||||
data PT_LOAD ;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
*(.text);
|
||||
*(.text.*);
|
||||
} : text
|
||||
|
||||
.rodata : {
|
||||
*(.rodata);
|
||||
*(.rodata.*);
|
||||
}
|
||||
|
||||
.data ALIGN(4) : {
|
||||
*(.plt);
|
||||
*(.data);
|
||||
*(.data.*);
|
||||
|
||||
/* bss section included to avoid missaligned segment */
|
||||
*(.bss);
|
||||
*(.bss.*);
|
||||
*(COMMON);
|
||||
} : data
|
||||
}
|
|
@ -1,10 +1,5 @@
|
|||
#include "builtin.h"
|
||||
#include <kernel/devices/ubc.h>
|
||||
#include <lib/display.h>
|
||||
#include <lib/unistd.h>
|
||||
|
||||
// TODO: remove me !!
|
||||
extern void test(void);
|
||||
|
||||
VHEX_BUILTIN(fxdb)
|
||||
{
|
||||
|
@ -16,14 +11,6 @@ VHEX_BUILTIN(fxdb)
|
|||
dprint(0, 0, "FXDB - entry !!");
|
||||
dupdate();
|
||||
for (int i = 0 ; i < 9000000 ; i = i + 1);
|
||||
|
||||
int fion = fork();
|
||||
dclear();
|
||||
dprint(0, 0, "FXDB - entry !!");
|
||||
dprint(0, 1, "fork test = %d", fion);
|
||||
dupdate();
|
||||
for (int i = 0 ; i < 9000000 ; i = i + 1);
|
||||
|
||||
return (0);
|
||||
|
||||
// Open User Break Controller.
|
||||
|
@ -35,15 +22,15 @@ VHEX_BUILTIN(fxdb)
|
|||
// linker script.
|
||||
// This module is only on SH7305 - SH4 based MPU.
|
||||
// THis function SHOULD not be called !
|
||||
ubc_open();
|
||||
// ubc_open();
|
||||
|
||||
// Jump into the tested function.
|
||||
// @note:
|
||||
// Thus USC should be start after the jump.
|
||||
//
|
||||
test();
|
||||
// test();
|
||||
|
||||
// Power OFF UBC module.
|
||||
ubc_close();
|
||||
// ubc_close();
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "builtin.h"
|
||||
/*#include "builtin.h"
|
||||
#include <kernel/memory.h>
|
||||
#include <lib/display.h>
|
||||
|
||||
|
@ -57,4 +57,4 @@ VHEX_BUILTIN(ram)
|
|||
for (int i = 0 ; i < 9000000 ; i = i + 1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
}*/
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
#include <kernel/devices/tty.h>
|
||||
#include <lib/display.h>
|
||||
#include "util.h"
|
||||
|
||||
//TODO: documentation.
|
||||
int main(void)
|
||||
{
|
||||
char input[12];
|
||||
dclear();
|
||||
dprint(0, 0, "First user program !");
|
||||
dupdate();
|
||||
while (1);
|
||||
|
||||
|
||||
/* char input[12];
|
||||
int cmd_size;
|
||||
char **argv;
|
||||
int argc;
|
||||
|
@ -33,5 +39,5 @@ int main(void)
|
|||
tty_write(": command not found\n", 20);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
return (0);*/
|
||||
}
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
#include "util.h"
|
||||
#include "builtin.h"
|
||||
#include <lib/string.h>
|
||||
#include <lib/display.h>
|
||||
#include <lib/unistd.h>
|
||||
|
||||
//TODO: use agc, argv.
|
||||
int check_builtin(char *cmd)
|
||||
{
|
||||
extern uint32_t bbuiltin_section;
|
||||
/* extern uint32_t bbuiltin_section;
|
||||
extern uint32_t ebuiltin_section;
|
||||
struct builtin_s *list;
|
||||
int wstatus;
|
||||
pid_t pid;
|
||||
//pid_t pid;
|
||||
int i;
|
||||
|
||||
i = -1;
|
||||
|
@ -28,7 +26,7 @@ int check_builtin(char *cmd)
|
|||
|
||||
// If we are the child execute
|
||||
// the builtins.
|
||||
//if (pid == 0)
|
||||
*/ //if (pid == 0)
|
||||
//{
|
||||
/*dclear();
|
||||
dprint(0, 0, "Child process !!");
|
||||
|
@ -36,12 +34,12 @@ int check_builtin(char *cmd)
|
|||
dprint(0, 2, "PPID = %d", getppid());
|
||||
dupdate();*/
|
||||
|
||||
list[i].entry(0, NULL);
|
||||
// list[i].entry(0, NULL);
|
||||
return (0);
|
||||
// } else {
|
||||
// waitpid(pid, &wstatus, WCONTINUED);
|
||||
//TODO: signal handling.
|
||||
// }
|
||||
}
|
||||
return (1);
|
||||
// }
|
||||
// return (1);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue