Fix crash with the UBC handler + Add VBR space
This commit is contained in:
parent
44ace2e56a
commit
659f631469
3
Makefile
3
Makefile
|
@ -81,6 +81,9 @@ check:
|
|||
map:
|
||||
@ $(OBJDUMP) -D $(DEBUG)/$(NAME).elf | less
|
||||
|
||||
bin:
|
||||
@ cat $(MEMORY_MAP) | less
|
||||
|
||||
|
||||
##---
|
||||
## Automated rules
|
||||
|
|
|
@ -21,7 +21,8 @@ typedef struct ubc_session_s
|
|||
uint32_t cursor;
|
||||
} context;
|
||||
struct {
|
||||
uint32_t cursor;
|
||||
int32_t vcursor;
|
||||
int32_t hcursor;
|
||||
} disassembly;
|
||||
} menu;
|
||||
struct ubc_context_s *context;
|
||||
|
|
|
@ -15,7 +15,10 @@ struct opcode_s
|
|||
uint16_t mask;
|
||||
uint16_t code;
|
||||
uint16_t arg_mask[ARGUMENTS_MAX];
|
||||
void (*special)(char *buffer, struct opcode_s);
|
||||
void (*special)(char *buffer, uint16_t *area);
|
||||
};
|
||||
|
||||
// Opcode list.
|
||||
extern const struct opcode_s opcode_list[];
|
||||
|
||||
#endif /*__OPCODE_H__*/
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
extern void dclear(void);
|
||||
extern void dprint(int x, int y, char const *str, ...);
|
||||
extern void dascii(int x, int y, char const c);
|
||||
extern void dreverse(int x, int y, int width, int height);
|
||||
extern void dscroll(int line);
|
||||
extern void dupdate(void);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <kernel/devices/ubc.h>
|
||||
#include <kernel/syscall.h>
|
||||
#include <kernel/types.h>
|
||||
#include <kernel/extra.h>
|
||||
#include <lib/display.h>
|
||||
#include <lib/string.h>
|
||||
|
||||
|
@ -19,18 +20,18 @@ extern uint32_t sdata;
|
|||
extern uint32_t bvhex_ram;
|
||||
extern uint32_t bvhex_rom;
|
||||
extern uint32_t svhex;
|
||||
extern uint32_t btest_ram;
|
||||
extern uint32_t btest_rom;
|
||||
extern uint32_t stest;
|
||||
extern uint32_t bubc_ram;
|
||||
extern uint32_t bubc_rom;
|
||||
extern uint32_t subc;
|
||||
|
||||
|
||||
// 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 void ubc_handler(void);
|
||||
extern mpu_t mpu_get(void);
|
||||
extern void ubc_handler_pre(void);
|
||||
extern void test(void);
|
||||
extern int main(void);
|
||||
|
||||
|
||||
__attribute__((section(".pretext")))
|
||||
int start(void)
|
||||
{
|
||||
|
@ -39,13 +40,32 @@ int start(void)
|
|||
|
||||
// Wipe .bss section and dump .data / Vhex sections
|
||||
memset(&bbss, 0x00, (size_t)&sbss);
|
||||
memcpy(&bubc_ram, &bubc_rom, (size_t)&subc);
|
||||
memcpy(&bdata_ram, &bdata_rom, (size_t)&sdata);
|
||||
//memcpy(&bvhex_ram, &bvhex_rom, (size_t)&svhex);
|
||||
//memcpy(&btest_ram, &btest_rom, (size_t)&stest);
|
||||
memcpy(&bvhex_ram, &bvhex_rom, (size_t)&svhex);
|
||||
|
||||
// Get Casio's VRAM address.
|
||||
// Get Casio's VRAM
|
||||
display_open();
|
||||
|
||||
/* volatile uint32_t *bite = (void*)0xe5200000;
|
||||
|
||||
dclear();
|
||||
dprint(0, 0, "UBC = %p", &ubc_handler_pre);
|
||||
dprint(0, 1, "TEST = %#x", *bite);
|
||||
dprint(0, 2, "TEST = %#x", *(uint32_t*)&bubc_rom);
|
||||
dprint(0, 3, "TEST = %#x", (uint32_t)&bubc_ram);
|
||||
dprint(0, 4, "TEST = %#x", (uint32_t)&bubc_rom);
|
||||
dprint(0, 5, "TEST = %#x", (size_t)&subc);
|
||||
dupdate();
|
||||
while (1);*/
|
||||
|
||||
// Check MPU hardware.
|
||||
current_mpu = mpu_get();
|
||||
if (current_mpu != MPU_SH7305)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
// Open User Break Controller.
|
||||
// @note:
|
||||
// This function is hardcoded to follow syscall
|
||||
|
|
|
@ -10,6 +10,16 @@
|
|||
extern void menu_context(ubc_session_t *session);
|
||||
extern void menu_disassembly(ubc_session_t *session);
|
||||
|
||||
void ubc_module_handler(int action)
|
||||
{
|
||||
/* dclear();
|
||||
dprint(0, 0, "spc = %p", action);
|
||||
dupdate();
|
||||
for (int i = 0 ; i < 4000000 ; i = i + 1);
|
||||
|
||||
*/ //TODO stop all clock / timer.
|
||||
}
|
||||
|
||||
void ubc_handler(struct ubc_context_s *context, int channel)
|
||||
{
|
||||
void (*menu)(ubc_session_t *session);
|
||||
|
@ -20,7 +30,8 @@ void ubc_handler(struct ubc_context_s *context, int channel)
|
|||
session.channel = channel;
|
||||
session.context = context;
|
||||
session.menu.context.cursor = 0;
|
||||
session.menu.disassembly.cursor = 0;
|
||||
session.menu.disassembly.vcursor = -(DISPLAY_VLINES_MAX >> 1);
|
||||
session.menu.disassembly.hcursor = 0;
|
||||
|
||||
// Initialize menu function.
|
||||
menu = &menu_disassembly;
|
||||
|
@ -36,4 +47,11 @@ void ubc_handler(struct ubc_context_s *context, int channel)
|
|||
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.
|
||||
icbi((void*)0xa0000000);
|
||||
}
|
||||
|
|
|
@ -1,34 +1,32 @@
|
|||
.section ".ubc.handler", "awx", @progbits
|
||||
|
||||
.global _ubc_handler_pre
|
||||
.type _ubc_handler_pre, @function
|
||||
|
||||
.extern _ubc_handler
|
||||
.extern _ubc_module_handler
|
||||
|
||||
|
||||
.text
|
||||
.align 2
|
||||
_ubc_handler_pre:
|
||||
! Stack management.
|
||||
stc.l spc, @-r15 ! Save SPC regsiter.
|
||||
stc.l ssr, @-r15 ! Save SSR regsiter.
|
||||
.word 0b0100111100110010 ! Save SGR register (save r15 address befor break) "stc.l sgr, @-r15"
|
||||
mov.l r8, @-r15 ! Save r8 register.
|
||||
mov.l r9, @-r15 ! Save r9 register.
|
||||
mov.l r8, @-r15 ! Save r8 register.
|
||||
sts.l pr, @-r15 ! Save pr regsiter.
|
||||
mov r15, r0 ! Save stack address. (used for UBC context)
|
||||
|
||||
! Generate UBC context
|
||||
! Generate "programe" context (used by the UBC handler)
|
||||
stc.l spc, @-r15 ! Get SPC register.
|
||||
stc.l ssr, @-r15 ! Get SSR register.
|
||||
sts.l mach, @-r15 ! Get MACH register.
|
||||
sts.l macl, @-r15 ! Get MACL register.
|
||||
stc.l gbr, @-r15 ! Get GBR register.
|
||||
.word 0b0100111100110010 ! Get SGR register (save r15 address befor break) "stc.l sgr, @-r15"
|
||||
mov.l r14, @-r15 ! Get 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 r14, @-r15 ! Get "program" r14 register.
|
||||
mov.l r13, @-r15 ! Get "program" r13 register.
|
||||
mov.l r12, @-r15 ! Get "program" r12 register.
|
||||
mov.l r11, @-r15 ! Get "program" r11 register.
|
||||
mov.l r10, @-r15 ! Get "program" r10 register.
|
||||
mov.l r9, @-r15 ! Get "program" r9 register.
|
||||
mov.l r8, @-r15 ! Get "program" r8 register.
|
||||
stc.l R7_BANK, @-r15 ! Get "program" r7 regsiter.
|
||||
stc.l R6_BANK, @-r15 ! Get "program" r6 regsiter.
|
||||
|
@ -39,49 +37,79 @@ _ubc_handler_pre:
|
|||
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.
|
||||
! We need to stop (and save) all clocks / timers
|
||||
! before do any job.
|
||||
mov.l .ubc_module_handler, r0 ! Get high level abstraction for handle hardware module.
|
||||
jsr @r0 ! call ubc_module(MODULE_STOP)
|
||||
mov #0, r4 ! (db) r4 = MODULE_STOP
|
||||
|
||||
! Get which channel is trigger and clear interrupt Flags.
|
||||
mov.l .ubc_ccmfr, r0 ! Get UBC.CCMFR register
|
||||
mov.l @r0, r10 ! r10 = UBC.CCMFR. (save register)
|
||||
mov.l @r0, r9 ! r5 = UBC.CCMFR. (save register)
|
||||
mov #0, r1 ! r2 = 0x00000000 (clear flags)
|
||||
mov.l r1, @r0 ! Clear UBC.CCMFR.MF1 = 0 and UBC.CCMFR.MF1 = 0
|
||||
mov.l .icbi_addr, r2 ! Get P2 area for ICBI instruction.
|
||||
.word 0b0000001011100011 ! SH4 instruction "icbi @r2"
|
||||
|
||||
! Allow / unblock interrupt and switch register bank !
|
||||
stc sr, r9 ! Save SR register.
|
||||
mov r9, r1 ! Get SR register.
|
||||
stc sr, r8 ! Save SR register.
|
||||
mov r8, r1 ! Get SR register.
|
||||
mov.l .sr_mask, r0 ! Get SR mask for SR.BL, SR.IMASK and SR.RB
|
||||
and r0, r1 ! SR.BL = 0, SR.IMASK = 0b0000 and SR.RB = 0
|
||||
ldc r1, sr ! Update SR register.
|
||||
|
||||
! Call high-level abstraction
|
||||
mov r15, r4 ! Send UBC context object to the abstraction.
|
||||
mov r10, r5 ! Send which channel is trigger.
|
||||
mov r9, r5 ! Send which channel is trigger.
|
||||
mov.l .ubc_handler, r0 ! Get high-level abstraction address
|
||||
jsr @r0 ! Jump into it.
|
||||
nop ! (db) nop.
|
||||
|
||||
! Block interrupt
|
||||
ldc r9, sr ! Restore SR register (with SR.BL = 1 and SR.IMASK = 0b1111)
|
||||
! Block interrupt and switch
|
||||
! register bank
|
||||
ldc r8, sr ! Restore SR register (with SR.BL = 1, SR.IMASK = 0b1111, SR.RB = 1)
|
||||
|
||||
! Clean exit.
|
||||
mov r8, r15 ! Restore stack space.
|
||||
lds.l @r15+, pr ! Restor PR register.
|
||||
mov.l @r15+, r9 ! Restore r9 register.
|
||||
mov.l @r15+, r8 ! Restore r8 register.
|
||||
! Restore "program" context.
|
||||
ldc.l @r15+, R0_BANK ! Restore "program" r0 regsiter.
|
||||
ldc.l @r15+, R1_BANK ! Restore "program" r1 regsiter.
|
||||
ldc.l @r15+, R2_BANK ! Restore "program" r2 regsiter.
|
||||
ldc.l @r15+, R3_BANK ! Restore "program" r3 regsiter.
|
||||
ldc.l @r15+, R4_BANK ! Restore "program" r4 regsiter.
|
||||
ldc.l @r15+, R5_BANK ! Restore "program" r5 regsiter.
|
||||
ldc.l @r15+, R6_BANK ! Restore "program" r6 regsiter.
|
||||
ldc.l @r15+, R7_BANK ! Restore "program" r7 regsiter.
|
||||
mov.l @r15+, r8 ! Restore "program" r8 regsiter.
|
||||
mov.l @r15+, r9 ! Restore "program" r9 regsiter.
|
||||
mov.l @r15+, r10 ! Restore "program" r10 regsiter.
|
||||
mov.l @r15+, r11 ! Restore "program" r11 regsiter.
|
||||
mov.l @r15+, r12 ! Restore "program" r12 regsiter.
|
||||
mov.l @r15+, r13 ! Restore "program" r13 regsiter.
|
||||
mov.l @r15+, r14 ! Restore "program" r14 regsiter.
|
||||
.word 0b0100111100110110 ! Restore SGR regsiter. "ldc.l @r15+, sgr"
|
||||
ldc.l @r15+, gbr ! Get GBR register.
|
||||
lds.l @r15+, macl ! Get MACL register.
|
||||
lds.l @r15+, mach ! Get MACH register.
|
||||
ldc.l @r15+, ssr ! Restore SSR regsiter.
|
||||
ldc.l @r15+, spc ! Restore SPC regsiter.
|
||||
|
||||
! Retore and restart clock / timers
|
||||
stc spc, r4 ! (db) r4 = MODULE_START
|
||||
mov.l .ubc_module_handler, r0 ! Get high level abstraction for handle hardware module.
|
||||
jsr @r0 ! call ubc_module(MODULE_START)
|
||||
nop
|
||||
|
||||
! Clean exit.
|
||||
lds.l @r15+, pr ! Restor PR register.
|
||||
mov.l @r15+, r8 ! Restore r8 register.
|
||||
mov.l @r15+, r9 ! Restore r8 register.
|
||||
rte ! Interrupt Exit.
|
||||
nop ! (db) Safety first.
|
||||
|
||||
|
||||
.align 4
|
||||
.ubc_handler: .long _ubc_handler
|
||||
.ubc_ccmfr: .long 0xff200600
|
||||
.icbi_addr: .long 0xa0000000
|
||||
.sr_mask: .long ~(0x300000f0)
|
||||
.ubc_handler: .long _ubc_handler
|
||||
.ubc_module_handler: .long _ubc_module_handler
|
||||
.ubc_ccmfr: .long 0xff200600
|
||||
.icbi_addr: .long 0xa0000000
|
||||
.sr_mask: .long ~(0x300000f0)
|
||||
.end
|
||||
|
|
|
@ -1,10 +1,110 @@
|
|||
#include <kernel/devices/ubc.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_VLINES_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)
|
||||
{
|
||||
// test
|
||||
// Update cursor position.
|
||||
cursor_update(session);
|
||||
|
||||
// display ASM.
|
||||
dclear();
|
||||
dprint(0, 0, "Disassembly Menu !!");
|
||||
display_mnemonic(session);
|
||||
dupdate();
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,7 +23,7 @@ int ubc_open(void)
|
|||
casio_dbr = dbr_set(&ubc_handler_pre);
|
||||
|
||||
// Setup Channel 0.
|
||||
SH7305_UBC.CRR0.PCB = 0; // Set PC break before instruction break.
|
||||
SH7305_UBC.CRR0.PCB = 1; // Set PC break adter instruction break.
|
||||
SH7305_UBC.CRR0.BIE = 1; // Request a Break.
|
||||
|
||||
SH7305_UBC.CBR0.MFE = 0; // Enable Match Flag.
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
#include <lib/display.h>
|
||||
|
||||
__attribute__((section(".vhex.exception"), interrupt_handler))
|
||||
void exception_handler(void)
|
||||
{
|
||||
uint32_t spc;
|
||||
uint32_t ssr;
|
||||
uint32_t sr;
|
||||
|
||||
|
||||
// Get some registers's data.
|
||||
__asm__ volatile (
|
||||
"stc spc, %0;"
|
||||
"stc ssr, %1;"
|
||||
"stc sr, %2"
|
||||
: "=r"(spc), "=r"(ssr), "=r"(sr)
|
||||
:
|
||||
:
|
||||
);
|
||||
|
||||
// Write exception informations.
|
||||
dclear();
|
||||
dprint(0, 0,
|
||||
"Ho crap ! Exception !\n"
|
||||
"tra: %#x\n"
|
||||
"expevt: %#x\n"
|
||||
"spc: %#x\n"
|
||||
"ssr: %#x\n"
|
||||
"sr: %#x",
|
||||
*((uint32_t *)0xff000020),
|
||||
*((uint32_t *)0xff000024),
|
||||
spc,
|
||||
ssr,
|
||||
sr
|
||||
);
|
||||
dupdate();
|
||||
while (1);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#include <lib/display.h>
|
||||
|
||||
__attribute__((section(".vhex.interrupt"), interrupt_handler))
|
||||
void interrupt_handler(void)
|
||||
{
|
||||
dclear();
|
||||
dprint(0, 0, "Interrupt handler (%#x)\n", *(uint32_t*)0xff000028);
|
||||
dupdate();
|
||||
while (1);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
#include <lib/display.h>
|
||||
|
||||
__attribute__((section(".glados.tlb"), interrupt_handler))
|
||||
void tlb_handler(void)
|
||||
{
|
||||
uint32_t spc;
|
||||
uint32_t ssr;
|
||||
uint32_t sr;
|
||||
|
||||
|
||||
// Get some registers's data.
|
||||
__asm__ volatile (
|
||||
"stc spc, %0;"
|
||||
"stc ssr, %1;"
|
||||
"stc sr, %2"
|
||||
: "=r"(spc), "=r"(ssr), "=r"(sr)
|
||||
:
|
||||
:
|
||||
);
|
||||
|
||||
// Write exception informations.
|
||||
dclear();
|
||||
dprint(0, 0,
|
||||
"Ho crap ! Exception !\n"
|
||||
"tra: %#x\n"
|
||||
"expevt: %#x\n"
|
||||
"spc: %#x\n"
|
||||
"ssr: %#x\n"
|
||||
"sr: %#x",
|
||||
*((uint32_t *)0xff000020),
|
||||
*((uint32_t *)0xff000024),
|
||||
spc,
|
||||
ssr,
|
||||
sr
|
||||
);
|
||||
dupdate();
|
||||
while (1);
|
||||
}
|
|
@ -6,6 +6,7 @@ void dprint(int x, int y, char const *str, ...)
|
|||
{
|
||||
char buffer[512];
|
||||
int default_pos_x;
|
||||
int starting_x;
|
||||
va_list ap;
|
||||
int i;
|
||||
|
||||
|
@ -16,6 +17,7 @@ void dprint(int x, int y, char const *str, ...)
|
|||
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;
|
||||
|
@ -27,6 +29,12 @@ void dprint(int x, int y, char const *str, ...)
|
|||
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;
|
||||
}
|
||||
dascii(x, y, buffer[i]);
|
||||
x = x + KERNEL_FONT_REAL_WIDTH + 1;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
#include <lib/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.
|
||||
vram_offset_y = (y + height - 1) << 4;
|
||||
|
||||
while (--height >= 0)
|
||||
{
|
||||
j = width + x;
|
||||
while (--j >= x)
|
||||
{
|
||||
vram[(j >> 3) + vram_offset_y] ^= 0x80 >> (j & 7);
|
||||
}
|
||||
vram_offset_y = vram_offset_y - 16;
|
||||
}
|
||||
}
|
|
@ -1,38 +1,36 @@
|
|||
//#include <lib/stdio.h>
|
||||
//#include <lib/display.h>
|
||||
//#include <kernel/tty.h>
|
||||
/*#include <lib/stdio.h>
|
||||
#include <lib/display.h>
|
||||
|
||||
/*int main(void)
|
||||
// TODO: remove me !!
|
||||
extern void test(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char *line;
|
||||
|
||||
// Open TTY and display entry message
|
||||
tty_open();
|
||||
tty_write("Welcome to Vhex !\n");
|
||||
dclear();
|
||||
dprint(0, 0, "Boot complete !");
|
||||
dupdate();
|
||||
while (1);
|
||||
|
||||
|
||||
// UBC test !
|
||||
|
||||
// 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();
|
||||
|
||||
// Main loop
|
||||
while (1)
|
||||
{
|
||||
// Write input indications.
|
||||
// TODO: write current working directory ?
|
||||
tty_write(">");
|
||||
// Jump into the tested function.
|
||||
// @note:
|
||||
// Thus USC should be start after the jump.
|
||||
//
|
||||
//((void(*)(void))0x08100000)();
|
||||
//((void(*)(void))&vhex_dbr)();
|
||||
test();
|
||||
|
||||
// Get each line writen by the user.
|
||||
nbread = getline(&line, &size, 0);
|
||||
if (nbread == EOF)
|
||||
{
|
||||
// TODO: check jobs ?
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: do some job.
|
||||
}
|
||||
|
||||
// Close TTY and return.
|
||||
tty_close();
|
||||
return (0);
|
||||
// Power OFF UBC module.
|
||||
ubc_close();
|
||||
}*/
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include <kernel/syscall.h>
|
||||
/*#include <kernel/syscall.h>
|
||||
|
||||
void test(void)
|
||||
{
|
||||
uint8_t *vram;
|
||||
|
||||
vram = casio_Bdisp_GetVRAM();
|
||||
}
|
||||
}*/
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
.global _test
|
||||
.type _test, @function
|
||||
|
||||
.align 2
|
||||
_test:
|
||||
sts.l pr, @-r15
|
||||
|
||||
mov.l .syscall_vram, r0
|
||||
mov.l .syscall_entry, r1
|
||||
jsr @r1
|
||||
nop
|
||||
tst r0, r0
|
||||
bf _test
|
||||
nop
|
||||
|
||||
lds.l @r15+, pr
|
||||
rts
|
||||
nop
|
||||
|
||||
.align 4
|
||||
.syscall_entry: .long 0xa0010070
|
||||
.syscall_vram: .long 0x00000135
|
||||
.end
|
89
vhex.ld
89
vhex.ld
|
@ -10,10 +10,18 @@ MEMORY
|
|||
** This location is realy important because no Casio's OS data
|
||||
** should be overwrite (specially TLB information stored by Casio).
|
||||
*/
|
||||
bootram (rwx) : o = 0x88040000, l = 252k
|
||||
dbrram (rwx) : o = 0x8807f000, l = 4k
|
||||
rom (rx) : o = 0x00300200, l = 512k
|
||||
testram (rwx) : o = 0x08100000, l = 8k
|
||||
ram (WX) : o = 0x88040000, l = 252k
|
||||
rom (RX) : o = 0x00300200, l = 512k
|
||||
ilram (WX) : o = 0xe5200000, l = 4k
|
||||
}
|
||||
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD ;
|
||||
data PT_LOAD ;
|
||||
bss PT_NULL ;
|
||||
ubc PT_LOAD ;
|
||||
vbr PT_LOAD ;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
|
@ -29,13 +37,15 @@ SECTIONS
|
|||
. = ALIGN(4);
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
} > rom
|
||||
} > rom : text
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** RAM sctions
|
||||
*/
|
||||
. = ORIGIN(bootram);
|
||||
. = ORIGIN(ram);
|
||||
|
||||
/* BootStrap Stack: should be wiped later ! */
|
||||
/* (we force the section to be non loadable when the program is run) */
|
||||
|
@ -44,59 +54,25 @@ SECTIONS
|
|||
*(.bss)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
} > bootram :NONE
|
||||
} > ram : bss
|
||||
_sbss = SIZEOF(.bss);
|
||||
|
||||
/* Read-write data going to RAM */
|
||||
.data : ALIGN(4) {
|
||||
.data ALIGN(4) : ALIGN(4) {
|
||||
_bdata_rom = LOADADDR(.data) ;
|
||||
_bdata_ram = . ;
|
||||
|
||||
*(.data)
|
||||
|
||||
. = ALIGN(4);
|
||||
} > bootram AT> rom
|
||||
} > ram AT> rom : data
|
||||
_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 ALIGN(4) : SUBALIGN(4) {
|
||||
_bvhex_rom = LOADADDR(.vhex) ;
|
||||
_bvhex_ram = . ;
|
||||
_vhex_vbr = . - 0x100;
|
||||
|
@ -106,8 +82,29 @@ SECTIONS
|
|||
. = _vhex_vbr + 0x600 ;
|
||||
*(.vhex.interrupt) ;
|
||||
. = ALIGN(4);
|
||||
} > osram AT> rom
|
||||
_svhex = SIZEOF(.vhex);*/
|
||||
} > ram AT> rom : vbr
|
||||
_svhex = SIZEOF(.vhex);
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** DBR space !
|
||||
*/
|
||||
. = ORIGIN(ilram);
|
||||
.ubc ALIGN(4) : ALIGN(4) {
|
||||
_bubc_rom = LOADADDR(.ubc) ;
|
||||
_bubc_ram = . ;
|
||||
|
||||
*(.ubc.handler)
|
||||
*(.ubc)
|
||||
|
||||
. = ALIGN(4);
|
||||
} > ilram AT> rom : ubc
|
||||
_subc = SIZEOF(.ubc);
|
||||
|
||||
|
||||
|
||||
|
||||
/* unwanted section */
|
||||
/DISCARD/ : {
|
||||
|
|
Loading…
Reference in New Issue