Add UBC driver + UBC interrupt handler + UBC high level abstraction handler

This commit is contained in:
Yann MAGNIN 2019-12-06 23:45:04 +01:00
parent 84efc8c451
commit 856bb2ee57
42 changed files with 874 additions and 89 deletions

View File

@ -1,9 +1,7 @@
#!/usr/bin/make -f
## ---
## Project: sprite-coder
## Author:
## theo.cousinet@epitech.eu
## yann.magnin@epitech.eu
## Project: Vhex - On-calc debugger
## Author: yann.magnin@epitech.eu
## ---
##---
@ -23,6 +21,7 @@ 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 \
@ -79,6 +78,8 @@ check:
@ echo 'obj: $(OBJ)'
@ echo 'directory: $(DIRECTORY)'
map:
@ $(OBJDUMP) -D $(DEBUG)/$(NAME).elf | less
##---

10
include/kernel/dbr.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef __KERNEL_DBR_H__
# define __KERNEL_DBR_H__
#include <stddef.h>
#include <stdint.h>
extern void *dbr_set(void *dbr_new);
extern void *dbr_get(void);
#endif /*__KERNEL_DBR_H__*/

View File

@ -0,0 +1,11 @@
#ifndef __KERNEL_DEVICES_DISPLAY_H__
# define __KERNEL_DEVICES_DISPLAY_H__
#include <stddef.h>
#include <stdint.h>
// Primitives.
extern int display_open(void);
extern int display_close(void);
#endif /*__KERNEL_DEVICES_DISPLAY_H__*/

View File

@ -0,0 +1,21 @@
#ifndef __KERNEL_DEVICES_UBC_H__
# define __KERNEL_DEVICES_UBC_H__
#include <stddef.h>
#include <stdint.h>
typedef struct ubc_context_s
{
uint32_t reg[16];
uint32_t gbr;
uint32_t macl;
uint32_t mach;
uint32_t ssr;
uint32_t spc;
} ubc_context_t;
// Primitives.
extern int ubc_open(void);
extern int ubc_close(void);
#endif /*__KERNEL_DEVICES_UBC_H__*/

10
include/kernel/extra.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef __KERNEL_EXTRA_H__
# define __KERNEL_EXTRA_H__
#include <stddef.h>
#include <stdint.h>
// SH4-instruction
extern void icbi(void *area);
#endif /*__KERNEL_EXTRA_H__*/

View File

@ -3,8 +3,8 @@
#include <stdint.h>
#include <stddef.h>
#include <kernel/union_types.h>
#include <kernel/attributes.h>
#include <kernel/def/union_types.h>
#include <kernel/def/attributes.h>
struct SH7305_intc_s
{

View File

@ -3,8 +3,8 @@
#include <stdint.h>
#include <stddef.h>
#include <kernel/union_types.h>
#include <kernel/attributes.h>
#include <kernel/def/union_types.h>
#include <kernel/def/attributes.h>
struct sh7305_keysc_s
{

View File

@ -0,0 +1,101 @@
#ifndef __KERNEL_MODULES_SH7724_STANDBY_H__
# define __KERNEL_MODULES_SH7724_STANDBY_H__
#include <stdint.h>
#include <stddef.h>
#include <kernel/def/union_types.h>
#include <kernel/def/attributes.h>
struct power_s
{
volatile long_union(STBCR, /* Standby Control Register */
uint32_t const : 24;
uint32_t STBY : 1;
uint32_t const : 1;
uint32_t RSTBY : 1;
uint32_t USTBY : 1;
uint32_t const : 4;
);
GAPS(12);
volatile long_union(MSTPCR0, /* Module Stop Register 0 */
uint32_t TLB : 1; /* TLB */
uint32_t IC : 1; /* Instruction cache */
uint32_t OC : 1; /* Operand cache */
uint32_t RS : 1; /* RS memory */
uint32_t IL : 1; /* IL memory */
uint32_t SC : 1; /* Secondary cache */
uint32_t const : 1; /* All 0 */
uint32_t FPU : 1; /* Floating Point Unit */
uint32_t const : 1; /* All 0*/
uint32_t INTC : 1; /* Interrupt Controller */
uint32_t DMAC0 : 1; /* Direct Memory Access Controller 0 */
uint32_t SuperH : 1; /* SuperHyway */
uint32_t HUID : 1; /* User Debugging Interface */
uint32_t DBG : 1; /* Debugging function */
uint32_t UBC : 1; /* User Break Controller */
uint32_t const : 1; /* Reserved (R/W) */
uint32_t TMU0 : 1; /* Timer Unit 0 */
uint32_t CMT : 1; /* Compare Match Timer */
uint32_t RWDT : 1; /* Wathdog Timer */
uint32_t DMAC1 : 1; /* Direct Memory Access Controller 1 */
uint32_t const : 1; /* All 0 */
uint32_t TMU1 : 1; /* Timer Unit 1 */
uint32_t SCIF0 : 1; /* Serial Controller Interface 0 */
uint32_t SCIF1 : 1; /* Serial Controller Interface 1 */
uint32_t SCIF2 : 1; /* Serial Controller Interface 2 */
uint32_t SCIF3 : 1; /* Serial Controller Interface 3 */
uint32_t SCIF4 : 1; /* Serial Controller Interface 4 */
uint32_t SCIF5 : 1; /* Serial Controller Interface 5 */
uint32_t const : 1; /* All 0 */
uint32_t MSIOF0 : 1; /* Clock-synch. Serial Interface 0 */
uint32_t MSIOF1 : 1; /* Clock-synch. Serial Interface 0 */
uint32_t const : 1; /* All 0 */
);
volatile long_union(MSTPCR1, /* Module Stop Register 1 */
uint32_t const : 19; /* All 0 */
uint32_t KEYSC : 1; /* Key Scan Interface */
uint32_t RTC : 1; /* Real Time Clock */
uint32_t const : 1; /* All 0 */
uint32_t I2C0 : 1; /* I2C 0 */
uint32_t I2C1 : 1; /* I2C 1 */
uint32_t const : 8; /* All 0 */
);
volatile long_union(MSTPCR2, /* Module Stop Register 2 */
uint32_t const : 2; /* All 0 */
uint32_t MMC : 1; /* Multi Media Card Interface (?) */
uint32_t EMAC : 1; /* Ether Controller */
uint32_t const : 1; /* All 0 */
uint32_t ATAPI : 1; /* ATAPI */
uint32_t TPU : 1; /* Timer Pulse Unit */
uint32_t IrDA : 1; /* IrDA interface */
uint32_t const : 1; /* All 0 */
uint32_t TSIF : 1; /* TS interface */
uint32_t USB1 : 1; /* USB 1 */
uint32_t USB0 : 1; /* USB 0 */
uint32_t _2DG : 1; /* 2D graphics accelerator */
uint32_t SDHI0 : 1; /* SD card host */
uint32_t SDHI1 : 1; /* IrDA interface */
uint32_t const : 1; /* All 0 */
uint32_t VEU1 : 1; /* */
uint32_t const : 1; /* All 0 */
uint32_t CEU1 : 1; /* */
uint32_t BEU1 : 1; /* */
uint32_t const : 1; /* All 0 */
uint32_t _2DDMAC: 1; /* */
uint32_t SPU : 1; /* Sound Processing Unit */
uint32_t const : 1; /* All 0 */
uint32_t GCU : 1; /* */
uint32_t JPU : 1; /* JPEG processing Unit */
uint32_t VOU : 1; /* Video Output Unit */
uint32_t BEU0 : 1; /* */
uint32_t CEU0 : 1; /* */
uint32_t VPU : 1; /* Video Processing Unit */
uint32_t LCDC : 1; /* LCD controller */
);
GAPS(4);
volatile uint32_t const BAR; /* Boot Address Register */
};
#define SH7305_POWER (*(volatile struct power_s *)0xa4150020)
#endif /*__KERNEL_MODULES_SH7724_STANDBY_H__*/

View File

@ -0,0 +1,103 @@
#ifndef __KERNEL_HARDWARE_SH7305_UBC_H__
# define __KERNEL_HARDWARE_SH7305_UBC_H__
#include <stdint.h>
#include <stddef.h>
#include <kernel/def/union_types.h>
#include <kernel/def/attributes.h>
struct sh7305_ubc_s
{
//---
// Channel 0
//---
volatile long_union(CBR0,
uint32_t MFE : 1; /* Match Flag Enable */
uint32_t AIE : 1; /* ASID Enable */
uint32_t MFI : 6; /* Match Flag Specify */
uint32_t AIV : 8; /* ASID Specify */
uint32_t const : 1; /* All 0 */
uint32_t SZ : 3; /* Operend Size Select */
uint32_t const : 4; /* All 0 */
uint32_t CD : 2; /* Bus Select */
uint32_t ID : 2; /* Instruction Fetch / Operand Access Select */
uint32_t const : 1; /* All 0 */
uint32_t RW : 2; /* Bus Command Select */
uint32_t CE : 1; /* Channel Enable */
);
volatile long_union(CRR0,
uint32_t const : 18; /* All 0 */
uint32_t const : 1; /* All 1 */
uint32_t const : 11; /* All 0 */
uint32_t PCB : 1; /* PC Breack Select */
uint32_t BIE : 1; /* Breack Enable */
);
volatile uint32_t CAR0; /* Compare Address */
volatile uint32_t CAMR0; /* Compare Address Mask */
GAPS(0x10);
//---
// Channel 1
//---
volatile long_union(CBR1,
uint32_t MFE : 1; /* Match Flag Enable */
uint32_t AIE : 1; /* ASID Enable */
uint32_t MFI : 6; /* Match Flag Specify */
uint32_t AIV : 8; /* ASID Specify */
uint32_t DBE : 1; /* Data Value Enable */
uint32_t SZ : 3; /* Operend Size Select */
uint32_t ETBE : 1; /* Execution Count Value Enable */
uint32_t const : 3; /* All 0 */
uint32_t CD : 2; /* Bus Select */
uint32_t ID : 2; /* Instruction Fetch / Operand Access Select */
uint32_t const : 1; /* All 0 */
uint32_t RW : 2; /* Bus Command Select */
uint32_t CE : 1; /* Channel Enable */
);
volatile long_union(CRR1,
uint32_t const : 18; /* All 0 */
uint32_t const : 1; /* All 1 */
uint32_t const : 11; /* All 0 */
uint32_t PCB : 1; /* PC Breack Select */
uint32_t BIE : 1; /* Breack Enable */
);
volatile uint32_t CAR1; /* Compare Address */
volatile uint32_t CAMR1; /* Compare Address Mask */
//--
// Compare Data Part.
//---
volatile uint32_t CDR1; /* Compare Data Value */
volatile uint32_t CDMR1; /* Compare Data Value Mask */
//---
// Execution Count Register
//---
volatile long_union(CETR1,
uint32_t const : 20; /* All 0 */
uint32_t CET : 12; /* Execution Count */
);
GAPS(0x5c4);
//---
// Channel Match Flag Register
//---
volatile long_union(CCMFR,
uint32_t const : 30; /* All 0 */
uint32_t MF1 : 1; /* Channel 1 Condition Match Flag */
uint32_t MF0 : 1; /* Channel 0 Condition Match Flag */
);
GAPS(0x1c);
//---
// Control Register
//---
volatile long_union(CBCR,
uint32_t const : 31; /* All 0 */
uint32_t UBDE : 1; /* User Break Debugging Support Function Enable */
);
};
#define SH7305_UBC (*(volatile struct sh7305_ubc_s *)0xff200000)
#endif /*__KERNEL_HARDWARE_SH7305_UBC_H__*/

View File

@ -1,7 +1,8 @@
#ifndef __CASIO_H__
# define __CASIO_H__
#include <types.h>
#include <stdint.h>
#include <stddef.h>
// Internal Casio datat structure
struct rect
@ -42,9 +43,11 @@ void *casio_Malloc(size_t size);
/* Free() - free syscall */
void *casio_Free(void *ptr);
/* GetVRAM - Get the Video RAM used by Casio */
void *casio_Bdisp_GetVRAM(void);
// Internal casio abstraction.
static INLINE void dclear_area(int x1, int y1, int x2, int y2)
static inline void dclear_area(int x1, int y1, int x2, int y2)
{
struct rect area = {.left = x1, .top = y1, .right = x2, .bottom = y2};
casio_Bdisp_AreaClr_VRAM(&area);

11
include/kernel/vbr.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef __KERNEL_VBR_H__
# define __KERNEL_VBR_H__
#include <stddef.h>
#include <stdint.h>
// Vbr helper.
extern void *vbr_set(void *vbr_new);
extern void *vbr_get(void);
#endif /*__KERNEL_VBR_H__*/

View File

@ -27,6 +27,6 @@ extern void dscroll(int line);
extern void dupdate(void);
// Sheared Video RAM
extern uint32_t *VRAM;
extern uint8_t *vram;
#endif /*__LIB_DISPLAY_H__*/

View File

@ -6,7 +6,7 @@
#include <stdarg.h>
/* vsprintf(), sprintf() - formatted output conversion. */
void vsprintf(char *str, char const *format, va_list ap);
int vsprintf(char *str, char const *format, va_list ap);
void sprintf(char *str, char const *format, ...);
#endif /*__LIB_STDIO_H__*/

View File

@ -1,18 +1,14 @@
#include <stdint.h>
#include <stddef.h>
#include <kernel/context.h>
#include <kernel/atomic.h>
#include <kernel/devices/display.h>
#include <kernel/devices/ubc.h>
#include <kernel/syscall.h>
#include <kernel/types.h>
#include <lib/display.h>
#include <lib/string.h>
// Internal symbols
//uint32_t gcc_fix[256];
//uint32_t *VRAM = gcc_fix;
mpu_t current_mpu = MPU_UNKNOWN;
const char *casio_os_version = (void*)0xa0010020;
fx9860_context_t casio_context;
uint32_t casio_vbr;
// Symbols defined by the linker
extern uint32_t bbss;
@ -23,18 +19,72 @@ extern uint32_t sdata;
extern uint32_t bvhex_ram;
extern uint32_t bvhex_rom;
extern uint32_t svhex;
extern uint32_t vhex_vbr;
extern uint32_t btest_ram;
extern uint32_t btest_rom;
extern uint32_t stest;
// Internal functions.
extern void section_wipe(uint32_t *section, size_t size);
extern void section_load(uint32_t *dest, uint32_t *src, size_t size);
extern uint32_t vbr_set(uint32_t new_vbr);
extern uint32_t vbr_get(void);
extern mpu_t mpu_get(void);
extern void ubc_handler(void);
extern void test(void);
extern int main(void);
extern void vhex_context_set(void);
__attribute__((section(".pretext")))
int start(void)
{
unsigned int key;
void *casio_dbr;
// Wipe .bss section and dump .data / Vhex sections
memset(&bbss, 0x00, (size_t)&sbss);
memcpy(&bdata_ram, &bdata_rom, (size_t)&sdata);
//memcpy(&bvhex_ram, &bvhex_rom, (size_t)&svhex);
//memcpy(&btest_ram, &btest_rom, (size_t)&stest);
// Get Casio's VRAM address.
display_open();
// Open User Break Controller.
// @note:
// This function is hardcoded to follow syscall
// execution based on userland vitural address
// 0x08100000, reserved for add-in RAM.
// The tested programe is staticaly linked by the
// linker script.
// This module is only on SH7305 - SH4 based MPU.
// THis function SHOULD not be called !
ubc_open();
// Jump into the tested function.
// @note:
// Thus USC should be start after the jump.
//
//((void(*)(void))0x08100000)();
//((void(*)(void))&vhex_dbr)();
test();
// Power OFF UBC module.
ubc_close();
// Vhex's job is finished, display log.
dclear();
dprint(0, 0, "Vhex end !!\nNow wait [MENU] key press !");
dupdate();
// Wait [MENU] key is press.
while (1)
{
casio_GetKey(&key);
}
// Unused.
return (0);
}
/* Vhex with kernel version.
__attribute__((section(".pretext")))
int start(void)
{
@ -59,9 +109,6 @@ int start(void)
vhex_context_set();
atomic_end();
// VBR test.
__asm__ volatile ("trapa #0");
// Call high level abstraction.
error = main();
@ -73,7 +120,7 @@ int start(void)
// Return the abstraction error.
return (error);
}
}*/
//
// initialize() - kernel entry

32
src/kernel/dbr/handler.c Normal file
View File

@ -0,0 +1,32 @@
#include <kernel/devices/ubc.h>
#include <kernel/hardware/ubc.h>
#include <kernel/syscall.h>
#include <kernel/extra.h>
#include <lib/display.h>
void ubc_handler(ubc_context_t *context, int channel)
{
unsigned int key;
dclear();
dprint(0, 0,
"UBC INTERRUPT !!!!\n"
"context.spc = %p\n"
"context.ssr = %p\n"
"context.stack = %p\n"
"context = %p\n"
"UBC interrupt = %#x\n"
"Channel = %#x\n",
context->spc,
context->ssr,
context->reg[15],
context,
SH7305_UBC.CCMFR.LONG_WORD,
channel
);
dupdate();
while (1)
{
casio_GetKey(&key);
}
}

View File

@ -0,0 +1,81 @@
.global _ubc_handler_pre
.type _ubc_handler_pre, @function
.extern _ubc_handler
.text
.align 2
_ubc_handler_pre:
! Stack management.
mov.l r8, @-r15 ! Save r8 register.
mov.l r9, @-r15 ! Save r9 register.
sts.l pr, @-r15 ! Save pr regsiter.
mov r15, r0 ! Save stack address. (used for UBC context)
! Generate UBC context
mov r15, r1 ! Get current stack address.
add #12, r1 ! Get stack addres "before" UBC interrupt.
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.
mov.l r1, @-r15 ! Get "program" stack before UBC interrupt.
mov.l r14, @-r15 ! Get r14 register.
mov.l r13, @-r15 ! Get r13 register.
mov.l r12, @-r15 ! Get r12 register.
mov.l r10, @-r15 ! Get r10 register.
mov.l r11, @-r15 ! Get r11 register.
mov.l r9, @-r15 ! Get 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.
! Save stack address.
mov r0, r8 ! Save "original" stack address.
! Get which channel is trigger and clear interrupt Flags.
mov.l .ubc_ccmfr, r0 ! Get UBC.CCMFR register
mov.l @r0, r10 ! r10 = 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, r9 ! Save SR register.
mov r9, 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 r10, 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
ldc r9, sr ! Restore SR register (with SR.BL = 1 and SR.IMASK = 0b1111)
! Clean exit.
add r8, r15 ! Restore stack space.
mov.l @r15+, r9 ! Restore r9 register.
rte ! Interrupt Exit.
mov.l @r15+, r8 ! (db) Restore r8 register.
.align 4
.ubc_handler: .long _ubc_handler
.ubc_ccmfr: .long 0xff200600
.icbi_addr: .long 0xa0000000
.sr_mask: .long ~(0x300000f0)
.end

View File

@ -0,0 +1,7 @@
#include <kernel/devices/display.h>
int display_close(void)
{
// Do nothing for now.
return (0);
}

View File

@ -0,0 +1,12 @@
#include <kernel/devices/display.h>
#include <kernel/syscall.h>
// Create VRAM global.
uint8_t *vram = NULL;
int display_open(void)
{
//TODO: handle gxcg50 !!!
vram = casio_Bdisp_GetVRAM();
return (0);
}

View File

@ -1,4 +1,4 @@
#include <kernel/tty.h>
#include <kernel/devices/tty.h>
int tty_close(void)
{

View File

@ -1,4 +1,4 @@
#include <kernel/tty.h>
#include <kernel/devices/tty.h>
#include <lib/display.h>
// Internal TTY object.

View File

@ -1,4 +1,4 @@
#include <kernel/tty.h>
#include <kernel/devices/tty.h>
#include <lib/display.h>
// Internal TTY object.

View File

@ -0,0 +1,10 @@
#include <kernel/devices/ubc.h>
#include <kernel/hardware/power.h>
int ubc_close(void)
{
//FIXME: check MPU before call this function !!!
//FIXME: Disable all chennel before power OFF ?
SH7305_POWER.MSTPCR0.UBC = 1;
return (1);
}

View File

@ -0,0 +1,53 @@
#include <kernel/devices/ubc.h>
#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>
// 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)
{
//FIXME: check MPU before call this function !!!
// Power ON the User Break Controller.
SH7305_POWER.MSTPCR0.UBC = 0;
// Set Debug Based Register address.
casio_dbr = dbr_set(&ubc_handler_pre);
// Setup Channel 0.
SH7305_UBC.CRR0.PCB = 0; // Set PC break before instruction break.
SH7305_UBC.CRR0.BIE = 1; // Request a Break.
SH7305_UBC.CBR0.MFE = 0; // Enable Match Flag.
SH7305_UBC.CBR0.MFI = 0b000000; // Set UBC.CCMFR.MF0 = 1, when break occur.
SH7305_UBC.CBR0.AIE = 0; // Disable ASID check.
SH7305_UBC.CBR0.SZ = 0b010; // Disable Match condition.
SH7305_UBC.CBR0.CD = 0; // Use Operand Bus for Operand Access.
SH7305_UBC.CBR0.ID = 0b01; // Selecte instruction Fetch cycle.
SH7305_UBC.CBR0.RW = 0b11; // Use Read or Write for match condition.
SH7305_UBC.CBR0.CE = 0; // Disable Channel 0.
// Set up target address.
SH7305_UBC.CAR0 = (uint32_t)&test; // Tested programe address !
SH7305_UBC.CAMR0 = 0x00000000; // Address Mask.
// Setup Control register.
SH7305_UBC.CBCR.UBDE = 1; // Use DBR instead of VBR.
//@note:
// You *SHOULD* use `icbi` SH4 instruction
// After channel enable, otherwise the calculator
// will freeze.
SH7305_UBC.CBR0.CE = 1; // Enable Channel 0 !
icbi((void*)0xa0000000);
return (0);
}

19
src/kernel/util/dbr.s Normal file
View File

@ -0,0 +1,19 @@
.global _dbr_set
.global _dbr_get
.type _dbr_set, @function
.type _dbr_get, @function
.text
.align 2
_dbr_set:
.word 0b0000000011111010 ! SH4 intruction "stc dbr, r0"
.word 0b0100010011111010 ! SH4 intruction "ldc r4, dbr"
rts
nop
_dbr_get:
.word 0b0000000011111010 ! SH4 intruction "stc dbr, r0"
rts
nop
.end

9
src/kernel/util/extra.s Normal file
View File

@ -0,0 +1,9 @@
.global _icbi
.type _icbi, @function
.align 2
_icbi:
.word 0b0000010011100011 ! SH4 intstruction "icbi @r4"
rts ! exit
nop ! (db) nop.

189
src/kernel/util/syscall.s Normal file
View File

@ -0,0 +1,189 @@
.global _casio_Bdisp_PrintMini
.global _casio_Bdisp_PutDisp_DD
.global _casio_Bdisp_AllClr_VRAM
.global _casio_Bdisp_DrawLine_VRAM
.global _casio_Bdisp_AreaReverseVRAM
.global _casio_Bdisp_AreaClr_VRAM
.global _casio_Bdisp_GetVRAM
.global _casio_Bdisp_RestoreDisp
.global _casio_Bdisp_SaveDisp
.global _casio_Malloc
.global _casio_Free
.global _casio_GetKeyWait
.global _casio_GetKey
.global _casio_CreateFile
.global _casio_OpenFile
.global _casio_ReadFile
.global _casio_WriteFile
.global _casio_CloseFile
.type _casio_PrintMini, @function
.type _casio_Bdisp_PutDisp_DD, @function
.type _casio_Bdisp_AllClr_VRAM, @function
.type _casio_Bdisp_DrawLine_VRAM, @function
.type _casio_Bdisp_AreaReverseVRAM, @function
.type _casio_Bdisp_AreaClr_VRAM, @function
.type _casio_Bdisp_GetVRAM, @function
.type _casio_RestoreDisp, @function
.type _casio_SaveDisp, @function
.type _casio_Malloc, @function
.type _casio_Free, @function
.type _casio_GetKeyWait, @function
.type _casio_GetKey, @function
.type _casio_CreateFile, @function
.type _casio_OpenFile, @function
.type _casio_ReadFile, @function
.type _casio_WriteFile, @function
.type _casio_CloseFile, @function
.align 2
_casio_Bdisp_GetVRAM:
mov.l .syscall_entry, r1
mov.l .sys_getVRAM, r0
jmp @r1
nop
_casio_Bdisp_PrintMini:
mov.l .syscall_entry, r1
mov.l .sys_printMini, r0
jmp @r1
nop
_casio_Bdisp_AllClr_VRAM:
mov.l .syscall_entry, r1
mov.l .sys_clear, r0
jmp @r1
nop
_casio_Bdisp_PutDisp_DD:
mov.l .syscall_entry, r1
mov.l .sys_display, r0
jmp @r1
nop
_casio_Bdisp_DrawLine_VRAM:
mov.l .syscall_entry, r1
mov.l .sys_line, r0
jmp @r1
nop
_casio_Bdisp_AreaClr_VRAM:
mov.l .syscall_entry, r1
mov.l .sys_clear_area, r0
jmp @r1
nop
_casio_Bdisp_AreaReverseVRAM:
mov.l .syscall_entry, r1
mov.l .sys_reverse_area, r0
jmp @r1
nop
_casio_Bdisp_RestoreDisp:
mov.l .syscall_entry, r1
mov.l .sys_restore_disp, r0
jmp @r1
nop
_casio_Bdisp_SaveDisp:
mov.l .syscall_entry, r1
mov.l .sys_save_disp, r0
jmp @r1
nop
_casio_Malloc:
mov.l .syscall_entry, r1
mov.l .sys_malloc, r0
jmp @r1
nop
_casio_Free:
mov.l .syscall_entry, r1
mov.l .sys_free, r0
jmp @r1
nop
_casio_GetKey:
mov.l .syscall_entry, r1
mov.l .sys_getkey, r0
jmp @r1
nop
_casio_GetKeyWait:
mov.l .syscall_entry, r1
mov.l .sys_getkeywait, r0
jmp @r1
nop
_casio_CreateFile:
mov.l .syscall_entry, r1
mov.l .sys_createFile, r0
jmp @r1
nop
_casio_OpenFile:
mov.l .syscall_entry, r1
mov.l .sys_openFile, r0
jmp @r1
nop
_casio_WriteFile:
mov.l .syscall_entry, r1
mov.l .sys_writeFile, r0
jmp @r1
nop
_casio_ReadFile:
mov.l .syscall_entry, r1
mov.l .sys_readFile, r0
jmp @r1
nop
_casio_CloseFile:
mov.l .syscall_entry, r1
mov.l .sys_closeFile, r0
jmp @r1
nop
.align 4
.syscall_entry: .long 0x80010070
.sys_getVRAM: .long 0x00000135
.sys_line: .long 0x00000030
.sys_clear: .long 0x00000143 /*Bdisp_AllClr_VRAM */
.sys_getkey: .long 0x0000090f
.sys_display: .long 0x00000028
.sys_printMini: .long 0x00000c4f
.sys_clear_area: .long 0x0000014b
.sys_reverse_area: .long 0x0000014d
.sys_restore_disp: .long 0x00000814
.sys_save_disp: .long 0x00000813
.sys_malloc: .long 0x00000acd
.sys_free: .long 0x00000acc
.sys_createFile: .long 0x00000434
.sys_openFile: .long 0x0000042c
.sys_writeFile: .long 0x00000435
.sys_readFile: .long 0x00000432
.sys_closeFile: .long 0x0000042d
.sys_getkeywait: .long 0x00000247
.end

View File

@ -1,4 +1,4 @@
#include <lib/display.h>
/*#include <lib/display.h>
__attribute__((section(".vhex.exception"), interrupt_handler))
void exception_handler(void)
@ -35,4 +35,4 @@ void exception_handler(void)
);
dupdate();
while (1);
}
}*/

View File

@ -1,4 +1,4 @@
#include <lib/display.h>
/*#include <lib/display.h>
__attribute__((section(".vhex.interrupt"), interrupt_handler))
void interrupt_handler(void)
@ -7,4 +7,4 @@ void interrupt_handler(void)
dprint(0, 0, "Interrupt handler (%#x)\n", *(uint32_t*)0xff000028);
dupdate();
while (1);
}
}*/

View File

@ -1,4 +1,4 @@
#include <lib/display.h>
/*#include <lib/display.h>
__attribute__((section(".glados.tlb"), interrupt_handler))
void tlb_handler(void)
@ -35,4 +35,4 @@ void tlb_handler(void)
);
dupdate();
while (1);
}
}*/

View File

@ -83,11 +83,11 @@ void dascii(int x, int y, char const c)
// Calculate VRAM buffer starting position.
// @note:
// The screen width size is always 128 and we
// use 4-aligned Video RAM so 32 pixel 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 << 2;
// use 1-aligned Video RAM so 8 pixels per "slot"
// and 128 / 8 = 16
// y * 4 can be optimised by used shift operator,
// this is why we use y << 4 because 2^4 = 16.
vram_offset_y = y << 4;
// Draw character, pixer per pixel... (x_x)
i = -1;
@ -100,10 +100,10 @@ void dascii(int x, int y, char const c)
pixel_test = 0x80 >> (pixel_cursor & 0x07);
if (pixel_test & kernel_font_bitmap[pixel_cursor >> 3])
{
VRAM[((x + j) >> 5) + vram_offset_y] |= 0x80000000 >> ((x + j) & 0x1f);
vram[((x + j) >> 3) + vram_offset_y] |= 0x80 >> ((x + j) & 7);
}
}
bitmap_offset_y = bitmap_offset_y + KERNEL_FONT_BITMAP_WIDTH;
vram_offset_y = vram_offset_y + 4;
vram_offset_y = vram_offset_y + 16;
}
}

View File

@ -4,7 +4,7 @@ void dclear(void)
{
int i;
i = 256;
i = 1024;
while (--i >= 0)
VRAM[i] = 0x00000000;
vram[i] = 0x00000000;
}

View File

@ -8,19 +8,19 @@ void dscroll(int 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];
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] = 0x0000;
VRAM[i + 1] = 0x0000;
VRAM[i + 2] = 0x0000;
VRAM[i + 3] = 0x0000;
vram[i + 0] = 0x0000;
vram[i + 1] = 0x0000;
vram[i + 2] = 0x0000;
vram[i + 3] = 0x0000;
i = i + 4;
}
}

View File

@ -4,5 +4,5 @@
//FIXME: Check OS 3.00 !
void dupdate(void)
{
t6k11_display(VRAM);
t6k11_display(vram);
}

View File

@ -1,14 +1,16 @@
#include <lib/stdio.h>
#include <stdarg.h>
static size_t strbase(char *dest, uint32_t nb, size_t size, int base)
{
uint32_t tmp;
uint8_t neg;
if (base == 10){
if ((int32_t)nb < 0){
*(dest++) = '-';
nb = -nb;
}
neg = 0;
if (base == 10 && (int32_t)nb < 0){
*dest = '-';
nb = -nb;
neg = 1;
}
if (size == 0){
tmp = nb;
@ -19,37 +21,40 @@ static size_t strbase(char *dest, uint32_t nb, size_t size, int base)
if (size == 0)
size = 1;
}
tmp = size;
while ((int)(--size) >= 0){
tmp = size + neg;
while ((int)(--size) >= neg){
*(dest + size) = ((nb % base) + '0') + (39 * ((nb % base) > 9));
nb /= base;
}
*(dest + tmp) = '\0';
return (tmp);
}
static size_t strndump(char *dest, char const *str, size_t size)
static size_t strndump(char *dest, char const *src, size_t size)
{
size_t i;
if (str == NULL || dest == NULL)
if (src == NULL)
return (0);
i = -1;
while (++i < size && str[i] != '\0')
dest[i] = str[i];
while (++i < size && src[i] != '\0')
dest[i] = src[i];
dest[i] = '\0';
return (i);
}
void vsprintf(char *str, char const *format, va_list ap)
int vsprintf(char *str, char const *format, va_list ap)
{
const char *tmp;
void *sstr;
size_t size;
size_t len;
int nb;
if (format == NULL)
return;
if (format == NULL || str == NULL)
return (-1);
sstr = str;
while (*format != '\0'){
if (*format != '%'){
*(str++) = *(format++);
@ -61,6 +66,10 @@ void vsprintf(char *str, char const *format, va_list ap)
format += 1;
while (format[++len] >= '0' && format[len] <= '9')
size = size * 10 + format[len] - '0';
if (format[len] == '*'){
size = va_arg(ap, size_t);
format = format + 1;
}
if (format[len] == '%'){
*(str++) = '%';
format += 1;
@ -72,33 +81,34 @@ void vsprintf(char *str, char const *format, va_list ap)
continue;
}
if (format[len] == 's'){
char const *tmp = va_arg(ap, char const *);
tmp = va_arg(ap, const char *);
/* TODO: find better way to do the job */
str += strndump(str, tmp, (size == 0) ? 1024 : size);
format += len + 1;
continue;
}
if (format[len] == 'd'){
int nb = va_arg(ap, int);
nb = va_arg(ap, int);
str += strbase(str, nb, size, 10);
format += len + 1;
continue;
}
if (format[len] == 'x'){
int nb = va_arg(ap, int);
nb = va_arg(ap, int);
str += strbase(str, nb, size, 16);
format += len + 1;
continue;
}
if (format[len] == '#' && format[len + 1] == 'x'){
int nb = va_arg(ap, int);
if (format[len] == 'p' || (format[len] == '#' && format[len + 1] == 'x')){
nb = va_arg(ap, int);
*(str++) = '0';
*(str++) = 'x';
str += strbase(str, nb, 8, 16);
format += len + 2;
format += (format[len] == 'p') ? len + 1 : len + 2;
continue;
}
*(str++) = '%';
}
*str = '\0';
return ((int)((void *)str - (void *)sstr));
}

View File

@ -1,8 +1,8 @@
#include <lib/stdio.h>
#include <lib/display.h>
#include <kernel/tty.h>
//#include <lib/stdio.h>
//#include <lib/display.h>
//#include <kernel/tty.h>
int main(void)
/*int main(void)
{
char *line;
@ -10,6 +10,10 @@ int main(void)
tty_open();
tty_write("Welcome to Vhex !\n");
// UBC test !
// Main loop
while (1)
{
@ -18,12 +22,12 @@ int main(void)
tty_write(">");
// Get each line writen by the user.
/*nbread = getline(&line, &size, 0);
nbread = getline(&line, &size, 0);
if (nbread == EOF)
{
// TODO: check jobs ?
break;
}*/
}
// TODO: do some job.
}
@ -31,4 +35,4 @@ int main(void)
// Close TTY and return.
tty_close();
return (0);
}
}*/

8
src/user/test.c Normal file
View File

@ -0,0 +1,8 @@
#include <kernel/syscall.h>
void test(void)
{
uint8_t *vram;
vram = casio_Bdisp_GetVRAM();
}

BIN
vhex.g1a

Binary file not shown.

45
vhex.ld
View File

@ -11,8 +11,9 @@ MEMORY
** should be overwrite (specially TLB information stored by Casio).
*/
bootram (rwx) : o = 0x88040000, l = 252k
osram (rwx) : o = 0x8807f000, l = 4k
dbrram (rwx) : o = 0x8807f000, l = 4k
rom (rx) : o = 0x00300200, l = 512k
testram (rwx) : o = 0x08100000, l = 8k
}
SECTIONS
@ -50,20 +51,52 @@ SECTIONS
.data : ALIGN(4) {
_bdata_rom = LOADADDR(.data) ;
_bdata_ram = . ;
*(.data)
/* Video RAM space */
_VRAM = ALIGN(4);
. = (. + 1024);
. = ALIGN(4);
} > bootram AT> rom
_sdata = SIZEOF(.data);
/*
** TEST space !
*/
/*. = ORIGIN(testram);
.test : ALIGN(4) {
_btest_rom = LOADADDR(.test) ;
_btest_ram = . ;
*(.test.prgm)
. = ALIGN(4);
} > testram AT> rom
_stest = SIZEOF(.test);
*/
/*
** DBR space !
*/
/*. = ORIGIN(testram);
.vhex : ALIGN(4) {
_bvhex_rom = LOADADDR(.vhex) ;
_bvhex_ram = . ;
_vhex_dbr = . ;
*(.vhex.handler)
. = ALIGN(4);
} > osram AT> rom
_svhex = SIZEOF(.vhex);
*/
/*
** VBR space !
*/
/* Interrupt / exception handlers */
.vhex : SUBALIGN(4) {
/*.vhex : SUBALIGN(4) {
_bvhex_rom = LOADADDR(.vhex) ;
_bvhex_ram = . ;
_vhex_vbr = . - 0x100;
@ -74,7 +107,7 @@ SECTIONS
*(.vhex.interrupt) ;
. = ALIGN(4);
} > osram AT> rom
_svhex = SIZEOF(.vhex);
_svhex = SIZEOF(.vhex);*/
/* unwanted section */
/DISCARD/ : {