Compare commits

...

1 Commits

Author SHA1 Message Date
Yann MAGNIN 671c141d06 proof-of-concept of on-calc tracer (trace Bfile_OpenFile) 2020-05-28 18:33:46 +02:00
27 changed files with 4499 additions and 54 deletions

1
.gitignore vendored
View File

@ -61,3 +61,4 @@ debug_bin
output
gcc.cfg
.tests
a.out

View File

@ -6,7 +6,7 @@
#include <kernel/bits/union_types.h>
#include <kernel/bits/attributes.h>
struct sh7305_ubc_s
struct __sh7305_ubc
{
//---
// Channel 0
@ -99,5 +99,23 @@ struct sh7305_ubc_s
);
};
#define SH7305_UBC (*(volatile struct sh7305_ubc_s *)0xff200000)
// Hardware context
struct __sh7305_ubc_context
{
uint32_t cbr0;
uint32_t crr0;
uint32_t car0;
uint32_t camr0;
uint32_t cbr1;
uint32_t crr1;
uint32_t car1;
uint32_t camr1;
uint32_t cdr1;
uint32_t cdmr1;
uint32_t cetr1;
uint32_t ccmfr;
uint32_t cbr;
};
#define SH7305_UBC (*(volatile struct __sh7305_ubc *)0xff200000)
#endif /*__KERNEL_HARDWARE_SH7305_UBC_H__*/

View File

@ -0,0 +1,86 @@
#ifndef __KERNEL_UTIL_DISASM_H__
# define __KERNEL_UTIL_DISASM_H__
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
#include <kernel/bits/context.h>
// Define the number max of arguments
// for intrustions.
#define ARGUMENTS_MAX 3
/* sysname - syscall name */
struct sysname_s
{
uint32_t syscall;
const char *name;
};
/* addrname - address peripherals name */
struct addrpername_s
{
uint32_t address;
const char *name;
};
/* opcode - instruction data part. */
struct opcode_s
{
const char *name;
uint16_t mask;
uint16_t code;
struct {
uint16_t mask;
uint32_t (*special)(struct cpu_context *context, uint32_t argument);
} arg[ARGUMENTS_MAX];
};
typedef struct ubc_session_s
{
// Menu part
struct {
struct {
uint32_t cursor;
} context;
struct {
struct {
off_t vertical;
off_t horizontal;
} print_offset;
uint16_t *memory;
uint32_t next_break;
uint32_t next_instruction;
} disassembly;
} menu;
// Common part
struct cpu_context *context;
int channel;
// Common keyboard abstractions
struct {
uint16_t entry : 1;
uint16_t shift : 1;
uint16_t alpha : 1;
uint16_t optn : 1;
uint16_t left : 1;
uint16_t right : 1;
uint16_t up : 1;
uint16_t down : 1;
uint16_t plus : 1;
uint16_t minus : 1;
} key;
} ubc_session_t;
// Opcode list.
extern const struct opcode_s opcode_list[];
extern const struct addrpername_s sh7305_peripherals[];
// Functions
extern void disasm_menu_disassembly(ubc_session_t *session);
extern void disasm_menu_show_context(ubc_session_t *session);
extern const char *disasm_check_peripheral(uint32_t argument);
extern const char *disasm_check_syscalls(uint32_t argument);
#endif /*__KERNEL_UTIL_DISASM_H__*/

View File

@ -16,6 +16,8 @@ typedef struct display_s
// Internal pre-calculated value
int nb_char_width;
int ws_col;
int ws_row;
} display_t;
// Internal struct used to define font structure object.
@ -56,10 +58,13 @@ struct font_block_s
extern int dopen(display_t *disp, const char *fontname);
extern void dclear(display_t *disp);
extern void dascii(display_t *disp, int row, int colomn, char const c, int mode);
extern size_t dprint(display_t *disp, int x, int y, char const *str, ...);
//extern size_t dprint(display_t *disp, int x, int y, char const *str, ...);
extern void dprint(display_t *disp, int col, int row, const char *format);
extern void dscroll(display_t *disp, int line);
extern void dreverse(display_t *disp, int x, int y, int width, int height);
extern void drect(display_t *disp, int x, int y, int width, int height);
extern void dupdate(display_t *disp);
extern void dhline(display_t *disp, int x, int y, int width);
extern void dvline(display_t *disp, int x, int y, int height);
#endif /*__LIB_DISPLAY_H__*/

View File

@ -20,7 +20,7 @@ NAME := vhex
EXEC := $(OUTPUT)/$(NAME).g1a
LDFLAG := -T $(NAME).ld
MEMORY_MAP := $(DEBUG)/$(NAME).map
LIBS := -L../lib -lgcc -llibc -ldisplay
LIBS := -L../lib -llibc -ldisplay -lgcc
ICON := icon.bmp

View File

@ -102,6 +102,22 @@ int start(void)
bootstrap_filesystem_init();
// DEBUG -disasm
extern void disasm_main(void);
disasm_main();
//extern void ubc_handler(struct cpu_context *context, int channel);
//struct cpu_context context;
//ubc_handler(&context, 1);
//---
// Start first process !
//---

View File

@ -69,14 +69,14 @@ static void power_driver_uninstall(void)
vhex_power_context.bar = SH7305_POWER.BAR;
// Restore Casio context
SH7305_POWER.STBCR.LONG_WORD = casio_power_context.stbcr;
/* SH7305_POWER.STBCR.LONG_WORD = casio_power_context.stbcr;
SH7305_POWER.MSTPCR0.LONG_WORD = casio_power_context.mstpcr[0];
SH7305_POWER.MSTPCR1.LONG_WORD = casio_power_context.mstpcr[1];
SH7305_POWER.MSTPCR2.LONG_WORD = casio_power_context.mstpcr[2];
SH7305_POWER.BAR = casio_power_context.bar;
// Force CPU update
icbi((void*)0xa0000000);
icbi((void*)0xa0000000);*/
}
// Create driver object

View File

@ -0,0 +1,55 @@
#include <kernel/hardware/ubc.h>
#include <kernel/hardware/power.h>
#include <kernel/bits/driver.h>
#include <kernel/util/extra.h>
#include <string.h>
// Internal hardware context
struct __sh7305_ubc_context ubc_context;
// Internal global
int ubc_driver_is_installed = 0;
//@note: we known that Casio doesn't use the UBC module
static void sh7305_ubc_driver_install(void)
{
extern uint32_t vhex_dbr;
extern uint32_t bubc_ram;
extern uint32_t bubc_rom;
extern uint32_t subc;
// Check multiple installation
if (ubc_driver_is_installed != 0)
return;
// Dump UBC handler
memcpy(&bubc_ram, &bubc_rom, (size_t)&subc);
// Set the DBR
dbr_set(&vhex_dbr);
// Start User Break Controller
SH7305_POWER.MSTPCR0.UBC = 0;
// Default initialization
SH7305_UBC.CBR0.MFI = 0b000000;
SH7305_UBC.CBR0.CE = 0;
SH7305_UBC.CBR1.MFI = 0b000000;
SH7305_UBC.CBR1.CE = 0;
SH7305_UBC.CBCR.UBDE = 1;
}
static void sh7305_ubc_driver_uninstall(void)
{
// Nothing for now
// TODO: Casio seems to stop UBC module when power off occur
// SO, restore context if needed (?)
}
// Create driver object
VHEX_DRIVER(3, driver_ubc_sh7305) = {
.arch = MPU_SH7305,
.install = &sh7305_ubc_driver_install,
.uninstall = &sh7305_ubc_driver_uninstall,
.name = "intc"
};

View File

@ -0,0 +1,111 @@
.section ".ubc.handler", "awx", @progbits
.global _ubc_handler_pre
.type _ubc_handler_pre, @function
.extern _ubc_handler
.extern _ubc_module_handler
.align 2
_ubc_handler_pre:
! Generate "programme" context (used by the UBC handler)
sts.l pr, @-r15 ! Save pr regsiter.
stc.l spc, @-r15 ! Get SPC register.
stc.l ssr, @-r15 ! Get SSR register.
sts.l mach, @-r15 ! Get MACH register.
sts.l macl, @-r15 ! Get MACL register.
stc.l gbr, @-r15 ! Get GBR register.
.word 0b0100111100110010 ! Get SGR register (save r15 address befor break) "stc.l sgr, @-r15"
mov.l r14, @-r15 ! Get "program" r14 register.
mov.l r13, @-r15 ! Get "program" r13 register.
mov.l r12, @-r15 ! Get "program" r12 register.
mov.l r11, @-r15 ! Get "program" r11 register.
mov.l r10, @-r15 ! Get "program" r10 register.
mov.l r9, @-r15 ! Get "program" r9 register.
mov.l r8, @-r15 ! Get "program" r8 register.
stc.l R7_BANK, @-r15 ! Get "program" r7 regsiter.
stc.l R6_BANK, @-r15 ! Get "program" r6 regsiter.
stc.l R5_BANK, @-r15 ! Get "program" r5 regsiter.
stc.l R4_BANK, @-r15 ! Get "program" r4 regsiter.
stc.l R3_BANK, @-r15 ! Get "program" r3 regsiter.
stc.l R2_BANK, @-r15 ! Get "program" r2 regsiter.
stc.l R1_BANK, @-r15 ! Get "program" r1 regsiter.
stc.l R0_BANK, @-r15 ! Get "program" r0 regsiter.
! Get which channel is trigger
! and clear interrupt flags.
mov.l .ubc_ccmfr, r0 ! get UBC.CCMFR register
mov.l @r0, r9 ! r9 = 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"
! Save all hardware context and restore
! Vhex environement
mov.l .drivers_install, r0
jsr @r0
mov #0, r4
! Allow / unblock interrupt and switch register bank !
stc sr, r8 ! save SR register.
mov r8, r1 ! get SR register.
mov.l .sr_mask, r0 ! get SR mask for SR.BL, SR.IMASK and SR.RB
and r0, r1 ! SR.BL = 0, SR.IMASK = 0b0000 and SR.RB = 0
ldc r1, sr ! update SR register.
! Call high-level abstraction
mov r15, r4 ! Send UBC context object to the abstraction.
mov r9, r5 ! Send which channel is trigger.
mov.l .ubc_handler, r0 ! Get high-level abstraction address
jsr @r0 ! Jump into it.
nop ! (db) nop.
! Block interrupt and switch
! register bank
ldc r8, sr ! Restore SR register (with SR.BL = 1, SR.IMASK = 0b1111, SR.RB = 1)
! Retore Casio's environement
mov.l .drivers_uninstall, r0
jsr @r0
mov #0, r4
! 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.
lds.l @r15+, pr ! Restor PR register.
! Clean exit.
rte ! Interrupt Exit.
nop ! (db) Safety first.
.align 4
.ubc_handler: .long _ubc_handler
.drivers_install: .long _drivers_install
.drivers_uninstall: .long _drivers_uninstall
.ubc_ccmfr: .long 0xff200600
.icbi_addr: .long 0xa0000000
.sr_mask: .long ~(0x300000f0)
.end

View File

@ -3,7 +3,10 @@
__attribute__((section(".vhex.tlb"), interrupt_handler))
void tlb_handler(void)
{
uint32_t spc;
extern void exception_handler(void);
exception_handler();
/* uint32_t spc;
uint32_t ssr;
uint32_t sr;
@ -33,5 +36,5 @@ void tlb_handler(void)
ssr,
sr
);
while (1);
while (1);*/
}

View File

@ -55,7 +55,7 @@ ssize_t smemfs_USB3_read(void *inode, void *buf, size_t count, off_t pos)
drivers_uninstall(0);
//DEBUG
display_test(pathname);
//display_test(pathname);
// Open the file
read = -1;

View File

@ -0,0 +1,173 @@
#include <kernel/util/disasm.h>
#include <kernel/devices/earlyterm.h>
#include <kernel/drivers/screen.h>
#include <lib/display.h>
#include <lib/stdio.h>
#include <lib/string.h>
static void check_special_addr(ubc_session_t *session, uint32_t address, int mode)
{
extern struct earlyterm earlyterm;
const char *addrname;
char line[128];
// Check address validity
addrname = NULL;
if ((mode & 1) != 0)
addrname = disasm_check_peripheral(address);
if (addrname == NULL && (mode & 2) != 0)
addrname = disasm_check_syscalls(address);
if (addrname == NULL)
return;
// Update vertical counter if needed
if (session->menu.disassembly.print_offset.vertical != 0)
session->menu.disassembly.print_offset.vertical += 1;
// Generate and print line
sprintf(line, "@note: 0x%.8x -> %s\n", address, addrname);
dprint(&earlyterm.display,
session->menu.disassembly.print_offset.horizontal,
session->menu.disassembly.print_offset.vertical, line);
// Update vertical counter
session->menu.disassembly.print_offset.vertical += 1;
}
static uint32_t get_arg(ubc_session_t *session, uint16_t code,
const struct opcode_s *opcode, int id)
{
extern struct earlyterm earlyterm;
uint32_t argument;
int shift;
// Get arg shift.
shift = -1;
while (++shift < 16 && !(opcode->arg[id].mask & (0x01 << shift)));
// Get arguments
argument = (code & opcode->arg[id].mask) >> shift;
// Call specific argument function
if (opcode->arg[id].special != NULL)
argument = (*opcode->arg[id].special)(session->context, argument);
// Check special address and return
check_special_addr(session, argument, 3);
return (argument);
}
static void display_mnemonic(ubc_session_t *session)
{
extern struct earlyterm earlyterm;
char line[128];
uint16_t *area;
uint32_t sspc;
uint32_t spc;
int i;
int j;
// Get starting area.
area = session->menu.disassembly.memory;
// Main Loop.
i = -1;
spc = (uint32_t)area;
sspc = session->context->spc;
session->context->spc = (uint32_t)area;
session->menu.disassembly.print_offset.vertical= 0;
while ((int)session->menu.disassembly.print_offset.vertical < earlyterm.display.ws_row)
{
// Generate first part.
i = i + 1;
memset(line, 0x00, 128);
check_special_addr(session, (uint32_t)&area[i], 2);
sprintf(line, "%.8x %.4x ", (uint32_t)&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 common line.
sprintf(&line[14],
opcode_list[j].name,
get_arg(session, area[i], &opcode_list[j], 0),
get_arg(session, area[i], &opcode_list[j], 1),
get_arg(session, 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]);
// Update internal context
// TODO: update all registers (complet emulation ?)
session->context->spc = session->context->spc + 2;
// Display line
dprint(&earlyterm.display,
session->menu.disassembly.print_offset.horizontal,
session->menu.disassembly.print_offset.vertical, line);
// Highlight break line if needed.
if ((uint32_t)&area[i] == sspc)
{
dreverse(&earlyterm.display,
0, session->menu.disassembly.print_offset.vertical * (earlyterm.display.font->font.height + 1),
128, earlyterm.display.font->font.height + 1);
}
if (session->menu.disassembly.next_break != sspc && (uint32_t)&area[i] == session->menu.disassembly.next_break) {
drect(&earlyterm.display,
0, session->menu.disassembly.print_offset.vertical * (earlyterm.display.font->font.height + 1) - 1,
128, earlyterm.display.font->font.height + 1
);
}
// Update vertical counter
session->menu.disassembly.print_offset.vertical += 1;
}
// Restore saved SPC
session->context->spc = sspc;
}
static void cursor_update(ubc_session_t *session)
{
// Horizontal update.
if (session->key.left == 1)
session->menu.disassembly.print_offset.horizontal += 1;
if (session->key.right == 1)
session->menu.disassembly.print_offset.horizontal -= 1;
// Vertical update.
if (session->key.up == 1)
session->menu.disassembly.memory = &session->menu.disassembly.memory[-1];
if (session->key.down == 1)
session->menu.disassembly.memory = &session->menu.disassembly.memory[1];
// Move break point
if (session->key.plus == 1)
session->menu.disassembly.next_break += 2;
if (session->key.minus == 1)
session->menu.disassembly.next_break -= 2;
}
void disasm_menu_disassembly(ubc_session_t *session)
{
extern struct earlyterm earlyterm;
// Update cursor position.
cursor_update(session);
// display ASM.
dclear(&earlyterm.display);
display_mnemonic(session);
screen_update(earlyterm.display.vram);
}

View File

@ -0,0 +1,152 @@
#include <kernel/util/disasm.h>
#include <kernel/devices/earlyterm.h>
#include <kernel/drivers/keyboard.h>
#include <kernel/hardware/ubc.h>
#include <kernel/hardware/ubc.h>
#include <kernel/bits/context.h>
#include <kernel/util/extra.h>
#include <kernel/util/casio.h>
#include <kernel/driver.h>
#include <string.h>
void disasm_main(void)
{
extern void casio_syscall_test(void);
// Setup Channel 0.
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.
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)&casio_Bfile_ReadFile; // 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);
// Start disassembly
// TODO: thread !!
drivers_uninstall(0);
char buffer[128];
int handle = casio_Bfile_OpenFile(u"\\\\fls0\\vhex.g1a", 1);
earlyterm_write("handle -> %#x\n", handle);
DBG_WAIT;
DBG_WAIT;
DBG_WAIT;
casio_Bfile_ReadFile(handle, buffer, 128, 0);
casio_Bfile_CloseFile(handle);
drivers_install(0);
}
static void internal_GetKey(ubc_session_t *session, void (**menu)(ubc_session_t*))
{
keyscan_t keylist[KEYBOARD_NB_KEYS];
int i;
// Wipe key informations
session->key.entry = 0;
session->key.shift = 0;
session->key.left = 0;
session->key.right = 0;
session->key.up = 0;
session->key.down = 0;
session->key.optn = 0;
session->key.minus = 0;
session->key.plus = 0;
// Wait user interactions
keyboard_wait_event(keylist);
// Check all pressed keys
i = -1;
while (keylist[++i].keycode != KEY_UNUSED && i < KEYBOARD_NB_KEYS)
{
// Check key validity
if (!(keylist[i].counter == 1
|| (i == 0 && keylist[i].counter > 10 && (keylist[i].counter & 1) == 0)))
continue;
// Check special keys
switch (keylist[i].keycode)
{
case KEY_EXE: session->key.entry = 1; break;
case KEY_SHIFT: session->key.shift = 1; break;
case KEY_ALPHA: session->key.alpha = 1; break;
case KEY_OPTN: session->key.optn = 1; break;
case KEY_LEFT: session->key.left = 1; break;
case KEY_RIGHT: session->key.right = 1; break;
case KEY_UP: session->key.up = 1; break;
case KEY_DOWN: session->key.down = 1; break;
case KEY_PLUS: session->key.plus = 1; break;
case KEY_MINUS: session->key.minus = 1; break;
case KEY_F1: *menu = &disasm_menu_disassembly; break;
case KEY_F2: *menu = &disasm_menu_show_context; break;
case KEY_MENU: casio_return_menu(0); break;
}
}
}
void ubc_handler(struct cpu_context *context, int channel)
{
extern struct earlyterm earlyterm;
void (*menu)(ubc_session_t *session);
ubc_session_t session;
// Initialize new session.
session.key.entry = 0;
session.key.shift = 0;
session.key.left = 0;
session.key.right = 0;
session.key.up = 0;
session.key.minus = 0;
session.key.plus = 0;
session.key.optn = 0;
session.channel = channel;
session.context = context;
session.menu.context.cursor = 0;
// Initialize disassembly menu
session.menu.disassembly.memory = (void *)(ptrdiff_t)context->spc;
session.menu.disassembly.memory = &session.menu.disassembly.memory[-earlyterm.display.ws_row / 2];
session.menu.disassembly.print_offset.horizontal = -4;
session.menu.disassembly.print_offset.vertical = 0;
session.menu.disassembly.next_break = context->spc;
session.menu.disassembly.next_instruction = 0x00000000;
// Main loop.
menu = &disasm_menu_disassembly;
while (session.key.entry == 0 && session.key.optn == 0)
{
menu(&session);
internal_GetKey(&session, &menu);
}
// Workaround for skip instruction
if (session.key.optn == 1) {
session.context->spc = session.menu.disassembly.next_break;
}
// Update UBC
SH7305_UBC.CAR0 = session.menu.disassembly.next_break; // Update break address.
SH7305_UBC.CAMR0 = 0x00000000; // Update break address.
SH7305_UBC.CBR0.CE = 1; // Enable channel.
icbi((void*)0xa0000000);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,504 @@
#include <kernel/util/disasm.h>
const char *disasm_check_peripheral(uint32_t address)
{
for (int i = 0 ; sh7305_peripherals[i].name != NULL ;++i) {
if (sh7305_peripherals[i].address == address)
return (sh7305_peripherals[i].name);
}
return (NULL);
}
// Thank's Simon Lothar
const struct addrpername_s sh7305_peripherals[] = {
// Other registers
{.address = 0xff000020, .name = "TRA (Trap event)"},
{.address = 0xff000024, .name = "EXPEVT (Excetpion event)"},
{.address = 0xff2f0004, .name = "EXPMASK (Nonsupport exception event)"},
{.address = 0xff2f0000, .name = "CPUOPM (CPU Operation)"},
{.address = 0xff000030, .name = "PVR (Processor version)"},
{.address = 0xff000040, .name = "CVR (Cache version)"},
{.address = 0xff000044, .name = "PRR (Product version)"},
// PFC (Port function control)"},
{.address = 0xA4050100, .name = "PACR (Port A Control)"},
{.address = 0xA4050102, .name = "PBCR (Port B Control)"},
{.address = 0xA4050104, .name = "PCCR (Port C Control)"},
{.address = 0xA4050106, .name = "PDCR (Port D Control)"},
{.address = 0xA4050108, .name = "PECR (Port E Control)"},
{.address = 0xA405010A, .name = "PFCR (Port F Control)"},
{.address = 0xA405010C, .name = "PGCR (Port G Control)"},
{.address = 0xA405010E, .name = "PHCR (Port H Control)"},
{.address = 0xA4050110, .name = "PJCR (Port J Control)"},
{.address = 0xA4050112, .name = "PKCR (Port K Control)"},
{.address = 0xA4050114, .name = "PLCR (Port L Control)"},
{.address = 0xA4050116, .name = "PMCR (Port M Control)"},
{.address = 0xA4050118, .name = "PNCR (Port N Control)"},
{.address = 0xA405014C, .name = "PPCR (Port P Control)"},
{.address = 0xA405011A, .name = "PQCR (Port Q Control)"},
{.address = 0xA405011C, .name = "PRCR (Port R Control)"},
{.address = 0xA405011E, .name = "PSCR (Port S Control)"},
{.address = 0xA4050140, .name = "PTCR (Port T Control)"},
{.address = 0xA4050142, .name = "PUCR (Port U Control)"},
{.address = 0xA4050144, .name = "PVCR (Port V Control)"},
{.address = 0xA405014E, .name = "PSELA (Pin group A select)"},
{.address = 0xA4050150, .name = "PSELB (Pin group B select)"},
{.address = 0xA4050152, .name = "PSELC (Pin group C select)"},
{.address = 0xA4050154, .name = "PSELD (Pin group D select)"},
{.address = 0xA4050156, .name = "PSELE (Pin group E select)"},
{.address = 0xA405015E, .name = "PSELF (Pin group F select)"},
{.address = 0xA40501C8, .name = "PSELG (Pin group G select)"},
{.address = 0xA40501D6, .name = "PSELH (Pin group H select)"},
{.address = 0xA4050158, .name = "HIZCRA (Data pin Hi-Z control A)"},
{.address = 0xA405015A, .name = "HIZCRB (Data pin Hi-Z control B)"},
{.address = 0xA405015C, .name = "HIZCRC (Data pin Hi-Z control C)"},
{.address = 0xA4050180, .name = "MSELCRA (Module function select A)"},
{.address = 0xA4050182, .name = "MSELCRB (Module function select B)"},
{.address = 0xA4050186, .name = "DRVCRA (Buffer drive control A)"},
{.address = 0xA4050188, .name = "DRVCRB (Buffer drive control B)"},
{.address = 0xA405018A, .name = "DRVCRC (Buffer drive control C)"},
{.address = 0xA4050184, .name = "DRVCRD (Buffer drive control D)"},
{.address = 0xA40501C3, .name = "PULCRBSC (BSC pull-up/down control)"},
{.address = 0xA40501C5, .name = "PULCRTRST (TRST pull-up/down select)"},
{.address = 0xA4050190, .name = "PULCRA (Port A pull-up/down control)"},
{.address = 0xA4050191, .name = "PULCRB (Port B pull-up/down control)"},
{.address = 0xA4050192, .name = "PULCRC (Port C pull-up/down control)"},
{.address = 0xA4050193, .name = "PULCRD (Port D pull-up/down control)"},
{.address = 0xA4050194, .name = "PULCRE (Port E pull-up/down control)"},
{.address = 0xA4050195, .name = "PULCRF (Port F pull-up/down control)"},
{.address = 0xA4050196, .name = "PULCRG (Port G pull-up/down control)"},
{.address = 0xA4050197, .name = "PULCRH (Port H pull-up/down control)"},
{.address = 0xA4050198, .name = "PULCRJ (Port J pull-up/down control)"},
{.address = 0xA4050199, .name = "PULCRK (Port K pull-up/down control)"},
{.address = 0xA405019A, .name = "PULCRL (Port L pull-up/down control)"},
{.address = 0xA405019B, .name = "PULCRM (Port M pull-up/down control)"},
{.address = 0xA405019C, .name = "PULCRN (Port N pull-up/down control)"},
{.address = 0xA40501C6, .name = "PULCRP (Port P pull-up/down control)"},
{.address = 0xA405019D, .name = "PULCRQ (Port Q pull-up/down control)"},
{.address = 0xA405019E, .name = "PULCRR (Port R pull-up/down control)"},
{.address = 0xA405019F, .name = "PULCRS (Port S pull-up/down control)"},
{.address = 0xA40501C0, .name = "PULCRT (Port T pull-up/down control)"},
{.address = 0xA40501C1, .name = "PULCRU (Port U pull-up/down control)"},
{.address = 0xA40501C2, .name = "PULCRV (Port V pull-up/down control)"},
//IO (Port I/O)"},
{.address = 0xA4050128, .name = "PEDR (Port E data)"},
{.address = 0xA405012A, .name = "PFDR (Port F data)"},
{.address = 0xA405012C, .name = "PGDR (Port G data)"},
{.address = 0xA405012E, .name = "PHDR (Port H data)"},
{.address = 0xA4050130, .name = "PJDR (Port J data)"},
{.address = 0xA4050132, .name = "PKDR (Port K data)"},
{.address = 0xA4050134, .name = "PLDR (Port L data)"},
{.address = 0xA4050136, .name = "PMDR (Port M data)"},
{.address = 0xA4050138, .name = "PNDR (Port N data)"},
{.address = 0xA405016A, .name = "PPDR (Port P data)"},
{.address = 0xA405013A, .name = "PQDR (Port Q data)"},
{.address = 0xA405013C, .name = "PRDR (Port R data)"},
{.address = 0xA405013E, .name = "PSDR (Port S data)"},
{.address = 0xA4050160, .name = "PTDR (Port T data)"},
{.address = 0xA4050162, .name = "PUDR (Port U data)"},
{.address = 0xA4050164, .name = "PVDR (Port V data)"},
//INT (Interrupt)"},
{.address = 0xA4080000, .name = "IPRA (Interrupt priority A)"},
{.address = 0xA4080004, .name = "IPRB (Interrupt priority B)"},
{.address = 0xA4080008, .name = "IPRC (Interrupt priority C)"},
{.address = 0xA408000C, .name = "IPRD (Interrupt priority D)"},
{.address = 0xA4080010, .name = "IPRE (Interrupt priority E)"},
{.address = 0xA4080014, .name = "IPRF (Interrupt priority F)"},
{.address = 0xA4080018, .name = "IPRG (Interrupt priority G)"},
{.address = 0xA408001C, .name = "IPRH (Interrupt priority H)"},
{.address = 0xA4080020, .name = "IPRI (Interrupt priority I)"},
{.address = 0xA4080024, .name = "IPRJ (Interrupt priority J)"},
{.address = 0xA4080028, .name = "IPRK (Interrupt priority K)"},
{.address = 0xA408002C, .name = "IPRL (Interrupt priority L)"},
{.address = 0xA4140000, .name = "ICR0 (Interrupt control 0)"},
{.address = 0xA414001C, .name = "ICR1 (Interrupt control 1)"},
{.address = 0xA4140010, .name = "INTPRI00 (Interrupt priority for IRQ)"},
{.address = 0xA4140024, .name = "INTREQ00 (Interrupt request for IRQ)"},
{.address = 0xA4140044, .name = "INTMSK00 (Interrupt mask for IRQ)"},
{.address = 0xA4140064, .name = "INTMSKCLR00 (Interrupt mask clear for IRQ)"},
{.address = 0xA41400C0, .name = "NMIFCR (Interrupt control for NMI)"},
{.address = 0xA4700000, .name = "USERIMASK (User interrupt mask)"},
{.address = 0xFF000028, .name = "INTEVT (Interrupt event)"},
{.address = 0xA40501DC, .name = "PINTCRA (PINT control A)"},
{.address = 0xA40501DE, .name = "PINTCRB (PINT control B)"},
{.address = 0xA40501EA, .name = "PINTSRA (PINT status A)"},
{.address = 0xA40501EC, .name = "PINTSRB (PINT status B)"},
{.address = 0xA40501EE, .name = "PINTSRC (PINT status C)"},
{.address = 0xA40501FA, .name = "PINTSRD (PINT status D)"},
{.address = 0xA4080080, .name = "IMR0 (Interrupt mask 0)"},
{.address = 0xA40800C0, .name = "IMCR0 (Interrupt mask clear 0)"},
{.address = 0xA4080084, .name = "IMR1 (Interrupt mask 1)"},
{.address = 0xA40800C4, .name = "IMCR1 (Interrupt mask clear 1)"},
{.address = 0xA4080088, .name = "IMR2 (Interrupt mask 2)"},
{.address = 0xA40800C8, .name = "IMCR2 (Interrupt mask clear 2)"},
{.address = 0xA408008C, .name = "IMR3 (Interrupt mask 3)"},
{.address = 0xA40800CC, .name = "IMCR3 (Interrupt mask clear 3)"},
{.address = 0xA4080090, .name = "IMR4 (Interrupt mask 4)"},
{.address = 0xA40800D0, .name = "IMCR4 (Interrupt mask clear 4)"},
{.address = 0xA4080094, .name = "IMR5 (Interrupt mask 5)"},
{.address = 0xA40800D4, .name = "IMCR5 (Interrupt mask clear 5)"},
{.address = 0xA4080098, .name = "IMR6 (Interrupt mask 6)"},
{.address = 0xA40800D8, .name = "IMCR6 (Interrupt mask clear 6)"},
{.address = 0xA408009C, .name = "IMR7 (Interrupt mask 7)"},
{.address = 0xA40800DC, .name = "IMCR7 (Interrupt mask clear 7)"},
{.address = 0xA40800A0, .name = "IMR8 (Interrupt mask 8)"},
{.address = 0xA40800E0, .name = "IMCR8 (Interrupt mask clear 8)"},
{.address = 0xA40800A4, .name = "IMR9 (Interrupt mask 9)"},
{.address = 0xA40800E4, .name = "IMCR9 (Interrupt mask clear 9)"},
{.address = 0xA40800A8, .name = "IMR10 (Interrupt mask 10)"},
{.address = 0xA40800E8, .name = "IMCR10 (Interrupt mask clear 10)"},
{.address = 0xA40800AC, .name = "IMR11 (Interrupt mask 11)"},
{.address = 0xA40800EC, .name = "IMCR11 (Interrupt mask clear 11)"},
{.address = 0xA40800B0, .name = "IMR12 (Interrupt mask 12)"},
{.address = 0xA40800F0, .name = "IMCR12 (Interrupt mask clear 12)"},
//DMA (DMA Controller)"},
{.address = 0xFE008020, .name = "SAR0 (DMA0 Source address)"},
{.address = 0xFE008024, .name = "DAR0 (DMA0 Dest address)"},
{.address = 0xFE008028, .name = "TCR0 (DMA0 Count)"},
{.address = 0xFE00802C, .name = "CHCR0 (DMA0 Control)"},
{.address = 0xFE008030, .name = "SAR1 (DMA1 Source address)"},
{.address = 0xFE008034, .name = "DAR1 (DMA1 Dest address)"},
{.address = 0xFE008038, .name = "TCR1 (DMA1 Count)"},
{.address = 0xFE00803C, .name = "CHCR1 (DMA1 Control)"},
{.address = 0xFE008040, .name = "SAR2 (DMA2 Source address)"},
{.address = 0xFE008044, .name = "DAR2 (DMA2 Dest address)"},
{.address = 0xFE008048, .name = "TCR2 (DMA2 Count)"},
{.address = 0xFE00804C, .name = "CHCR2 (DMA2 Control)"},
{.address = 0xFE008050, .name = "SAR3 (DMA3 Source address)"},
{.address = 0xFE008054, .name = "DAR3 (DMA3 Dest address)"},
{.address = 0xFE008058, .name = "TCR3 (DMA3 Count)"},
{.address = 0xFE00805C, .name = "CHCR3 (DMA3 Control)"},
{.address = 0xFE008060, .name = "DMAOR (DMA Operation)"},
{.address = 0xFE008070, .name = "SAR4 (DMA4 Source address)"},
{.address = 0xFE008074, .name = "DAR4 (DMA4 Dest address)"},
{.address = 0xFE008078, .name = "TCR4 (DMA4 Count)"},
{.address = 0xFE00807C, .name = "CHCR4 (DMA4 Control)"},
{.address = 0xFE008080, .name = "SAR5 (DMA5 Source address)"},
{.address = 0xFE008084, .name = "DAR5 (DMA5 Dest address)"},
{.address = 0xFE008088, .name = "TCR5 (DMA5 Count)"},
{.address = 0xFE00808C, .name = "CHCR5 (DMA5 Control)"},
{.address = 0xFE008120, .name = "SARB0 (DMA0 Source address B)"},
{.address = 0xFE008124, .name = "DARB0 (DMA0 Dest address B)"},
{.address = 0xFE008128, .name = "TCRB0 (DMA0 Count B)"},
{.address = 0xFE008130, .name = "SARB1 (DMA1 Source address B)"},
{.address = 0xFE008134, .name = "DARB1 (DMA1 Dest address B)"},
{.address = 0xFE008138, .name = "TCRB1 (DMA1 Count B)"},
{.address = 0xFE008140, .name = "SARB2 (DMA2 Source address B)"},
{.address = 0xFE008144, .name = "DARB2 (DMA2 Dest address B)"},
{.address = 0xFE008148, .name = "TCRB2 (DMA2 Count B)"},
{.address = 0xFE008150, .name = "SARB3 (DMA3 Source address B)"},
{.address = 0xFE008154, .name = "DARB3 (DMA3 Dest address B)"},
{.address = 0xFE008158, .name = "TCRB3 (DMA3 Count B)"},
{.address = 0xFE009000, .name = "DMARS0 (DMA resource select 0)"},
{.address = 0xFE009004, .name = "DMARS1 (DMA resource select 1)"},
{.address = 0xFE009008, .name = "DMARS2 (DMA resource select 2)"},
// MMU (Memory Manager)"},
{.address = 0xFF000010, .name = "MMUCR (MMU Control)"},
{.address = 0xFF000000, .name = "PTEH (MMU Page table entry high)"},
{.address = 0xFF000004, .name = "PTEL (MMU Page table entry low)"},
{.address = 0xFF000034, .name = "PTEA (MMU Page table entry assistance)"},
{.address = 0xFF000008, .name = "TTB (MMU Translation table base)"},
{.address = 0xFF00000C, .name = "TEA (MMU TLB Exception address)"},
{.address = 0xFF000070, .name = "PASCR (Physical address control)"},
{.address = 0xFF000078, .name = "IRMCR (Instruction refetch inhibit control)"},
{.address = 0xF2000000, .name = "ITLBADDRA (ITLB Address Array)"},
{.address = 0xF3000000, .name = "ITLBDATAA1 (ITLB Data Array 1)"},
{.address = 0xF3800000, .name = "ITLBDATAA2 (ITLB Data Array 2)"},
{.address = 0xF6000000, .name = "00100000 dd UTLBADDRA (UTLB Address Array)"},
{.address = 0xF7000000, .name = "UTLBDATAA1 (UTLB Data Array 1)"},
{.address = 0xF7800000, .name = " 00100000 dd UTLBDATAA2 (UTLB Data Array 2)"},
{.address = 0xF6100000, .name = "PMBADDRA (PMB Address Array)"},
{.address = 0xF7100000, .name = "PMBDATAA (PMB Data Array)"},
//Cache (Cache control)"},
{.address = 0xFF00001C, .name = "CCR (Cache control)"},
{.address = 0xF0000000, .name = "ICADDRA (Instruction Cache Address Array)"},
{.address = 0xF1000000, .name = "ICDATAA (Instruction Cache Data Array)"},
{.address = 0xF4000000, .name = "OCADDRA (Operand Cache Address Array)"},
{.address = 0xF5000000, .name = "OCDATAA (Operand Cache Data Array)"},
//BSC (Bus control)"},
{.address = 0xFEC10048, .name = "RTCSR (Refresh timer control)"},
{.address = 0xFEC1004C, .name = "RTCNT (Refresh counter)"},
{.address = 0xFEC10050, .name = "RTCOR (Refresh constant)"},
{.address = 0xFEC10000, .name = "CMNCR (Bus Common control)"},
{.address = 0xFEC10004, .name = "CS0BCR (Bus control for CS0)"},
{.address = 0xFEC10008, .name = "CS2BCR (Bus control for CS2)"},
{.address = 0xFEC1000C, .name = "CS3BCR (Bus control for CS3)"},
{.address = 0xFEC10010, .name = "CS4BCR (Bus control for CS4)"},
{.address = 0xFEC10014, .name = "CS5ABCR (Bus control for CS5A)"},
{.address = 0xFEC10018, .name = "CS5BBCR (Bus control for CS5B)"},
{.address = 0xFEC1001C, .name = "CS6ABCR (Bus control for CS6A)"},
{.address = 0xFEC10020, .name = "CS6BBCR (Bus control for CS6B)"},
{.address = 0xFEC10024, .name = "CS0WCR (Wait control for CS0)"},
{.address = 0xFEC10028, .name = "CS2WCR (Wait control for CS2)"},
{.address = 0xFEC1002C, .name = "CS3WCR (Wait control for CS3)"},
{.address = 0xFEC10030, .name = "CS4WCR (Wait control for CS4)"},
{.address = 0xFEC10034, .name = "CS5AWCR (Wait control for CS5A)"},
{.address = 0xFEC10038, .name = "CS5BWCR (Wait control for CS5B)"},
{.address = 0xFEC1003C, .name = "CS6AWCR (Wait control for CS6A)"},
{.address = 0xFEC10040, .name = "CS6BWCR (Wait control for CS6B)"},
{.address = 0xFEC10044, .name = "SDCR (SDRAM control)"},
{.address = 0xFEC14000, .name = "SDMR2 (SDRAM mode for CS2)"},
{.address = 0xFEC15000, .name = "SDMR3 (SDRAM mode for CS3)"},
// Clock (Clock generation)"},
{.address = 0xA4150000, .name = "FRQCR (Frequency control)"},
{.address = 0xA4150008, .name = "FSICLKCR (FSI Clock control)"},
{.address = 0xA415003C, .name = "SPUCLKCR (SPU Clock control)"},
{.address = 0xA4150010, .name = "DDCLKCR (DD Clock control)"},
{.address = 0xA4150014, .name = "USBCLKCR (USB Clock control)"},
{.address = 0xA4150024, .name = "PLLCR (PLL1 control)"},
{.address = 0xA4150028, .name = "PLL2CR (PLL2 control)"},
{.address = 0xA4150050, .name = "FLLFRQ (FLL Multiplication control)"},
{.address = 0xA4150060, .name = "LSTATUS (Frequency change status)"},
{.address = 0xA4150044, .name = "SSCGCR (Spread spectrum control)"},
// RTC (Real-time clock)"},
{.address = 0xA413FEC0, .name = "R64CNT (64-Hz counter)"},
{.address = 0xA413FEC2, .name = "RSECCNT (Seconds counter)"},
{.address = 0xA413FEC4, .name = "RMINCNT (Minutes counter)"},
{.address = 0xA413FEC6, .name = "RHRCNT (Hours counter)"},
{.address = 0xA413FEC8, .name = "RWKCNT (Weekday counter)"},
{.address = 0xA413FECA, .name = "RDAYCNT (Date counter)"},
{.address = 0xA413FECC, .name = "RMONCNT (Months counter)"},
{.address = 0xA413FECE, .name = "RYRCNT (Years counter)"},
{.address = 0xA413FED0, .name = "RSECAR (Seconds alarm)"},
{.address = 0xA413FED2, .name = "RMINAR (Minutes alarm)"},
{.address = 0xA413FED4, .name = "RHRAR (Hours alarm)"},
{.address = 0xA413FED6, .name = "RWKAR (Weekday alarm)"},
{.address = 0xA413FED8, .name = "RDAYAR (Date alarm)"},
{.address = 0xA413FEDA, .name = "RMONAR (Months alarm)"},
{.address = 0xA413FEE0, .name = "RYRAR (Years alarm)"},
{.address = 0xA413FEDC, .name = "RCR1 (RTC control 1)"},
{.address = 0xA413FEDE, .name = "RCR2 (RTC control 2)"},
{.address = 0xA413FEE4, .name = "RCR3 (RTC control 3)"},
// WDT (Watchdog timer)"},
{.address = 0xA4520000, .name = "RWTCNT (Watchdog timer counter)"},
{.address = 0xA4520004, .name = "RWTCSR (Watchdog control)"},
// Power (Power-down modes)"},
{.address = 0xA4150020, .name = "STBCR (Standby control)"},
{.address = 0xA4150030, .name = "MSTPCR0 (Module stop 0)"},
{.address = 0xA4150038, .name = "MSTPCR2 (Module stop 2)"},
{.address = 0xA4150040, .name = "BAR (Boot address)"},
// TMU0 (Timer unit 0)"},
{.address = 0xA4490004, .name = "TSTR (Timer start)"},
{.address = 0xA4490008, .name = "TCOR0 (Timer 0 constant)"},
{.address = 0xA449000C, .name = "TCNT0 (Timer 0 counter)"},
{.address = 0xA4490010, .name = "TCR0 (Timer 0 control)"},
// TMU1 (Timer unit 1)"},
{.address = 0xA4490014, .name = "TCOR1 (Timer 1 constant)"},
{.address = 0xA4490018, .name = "TCNT1 (Timer 1 counter)"},
{.address = 0xA449001C, .name = "TCR1 (Timer 1 control)"},
// TMU2 (Timer unit 2)"},
{.address = 0xA4490020, .name = "TCOR2 (Timer 2 constant)"},
{.address = 0xA4490024, .name = "TCNT2 (Timer 2 counter)"},
{.address = 0xA4490028, .name = "TCR2 (Timer 2 control)"},
// CMT (Compare match timer)"},
{.address = 0xA44A0000, .name = "CMSTR (Compare match timer start)"},
{.address = 0xA44A0060, .name = "CMCSR (Compare match timer control)"},
{.address = 0xA44A0064, .name = "CMCNT (Compare match timer counter)"},
{.address = 0xA44A0068, .name = "CMCOR (Compare match timer constant)"},
// SCIF (Serial communication)"},
{.address = 0xA4410000, .name = "SCSMR (Serial Mode)"},
{.address = 0xA4410004, .name = "SCBRR (Serial Bit rate)"},
{.address = 0xA4410008, .name = "SCSCR (Serial Control)"},
{.address = 0xA441000C, .name = "SCFTDR (Serial Transmit data)"},
{.address = 0xA4410010, .name = "SCFSR (Serial Status)"},
{.address = 0xA4410014, .name = "SCFRDR (Serial Receive data)"},
{.address = 0xA4410018, .name = "SCFCR (Serial FIFO control)"},
{.address = 0xA441001C, .name = "SCFDR (Serial FIFO count)"},
{.address = 0xA4410024, .name = "SCLSR (Serial Line status)"},
// IIC (I2C communication)"},
{.address = 0xA4470000, .name = "ICDR (I2C bus data)"},
{.address = 0xA4470004, .name = "ICCR (I2C bus control)"},
{.address = 0xA4470008, .name = "ICSR (I2C bus status)"},
{.address = 0xA447000C, .name = "ICIC (I2C interrupt control)"},
{.address = 0xA4470010, .name = "ICCL (I2C clock control low)"},
{.address = 0xA4470014, .name = "ICCH (I2C clock control high)"},
// USB (USB 2 control)"},
{.address = 0xA4D80000, .name = "SYSCFG (System configuration control)"},
{.address = 0xA4D80002, .name = "BUSWAIT (CPU bus wait setting)"},
{.address = 0xA4D80004, .name = "SYSSTS (System configuration status)"},
{.address = 0xA4D80008, .name = "DVSTCTR (Device status control)"},
{.address = 0xA4D8000C, .name = "TESTMODE (Test mode)"},
{.address = 0xA4D80014, .name = "CFIFO (CFIFO port)"},
{.address = 0xA4D80018, .name = "D0FIFO (D0FIFO port)"},
{.address = 0xA4D8001C, .name = "D1FIFO (D1FIFO port)"},
{.address = 0xA4D80020, .name = "CFIFOSEL (CFIFO port select)"},
{.address = 0xA4D80022, .name = "CFIFOCTR (CFIFO port control)"},
{.address = 0xA4D80028, .name = "D0FIFOSEL (D0FIFO port select)"},
{.address = 0xA4D8002A, .name = "D0FIFOCTR (D0FIFO port control)"},
{.address = 0xA4D8002C, .name = "D1FIFOSEL (D1FIFO port select)"},
{.address = 0xA4D8002E, .name = "D1FIFOCTR (D1FIFO port control)"},
{.address = 0xA4D80030, .name = "INTENB0 (Interrupt enable 0)"},
{.address = 0xA4D80036, .name = "BRDYENB (BRDY interrupt enable)"},
{.address = 0xA4D80038, .name = "NRDYENB (NRDY interrupt enable)"},
{.address = 0xA4D8003A, .name = "BEMPENB (BEMP interrupt enable)"},
{.address = 0xA4D8003C, .name = "SOFCFG (SOF pin configuration)"},
{.address = 0xA4D80040, .name = "INTSTS0 (Interrupt status 0)"},
{.address = 0xA4D80046, .name = "BRDYSTS (BRDY interrupt status)"},
{.address = 0xA4D80048, .name = "NRDYSTS (NRDY interrupt status)"},
{.address = 0xA4D8004A, .name = "BEMPSTS (BEMP interrupt status)"},
{.address = 0xA4D8004C, .name = "FRMNUM (Frame number)"},
{.address = 0xA4D8004E, .name = "UFRMNUM (mFrame number)"},
{.address = 0xA4D80050, .name = "USBADDR (USB address)"},
{.address = 0xA4D80054, .name = "USBREQ (USB request type)"},
{.address = 0xA4D80056, .name = "USBVAL (USB request value)"},
{.address = 0xA4D80058, .name = "USBINDX (USB request index)"},
{.address = 0xA4D8005A, .name = "USBLENG (USB request length)"},
{.address = 0xA4D8005C, .name = "DCPCFG (DCP configuration)"},
{.address = 0xA4D8005E, .name = "DCPMAXP (DCP max packet size)"},
{.address = 0xA4D80060, .name = "DCPCTR (DCP control)"},
{.address = 0xA4D80064, .name = "PIPESEL (Pipe window select)"},
{.address = 0xA4D80068, .name = "PIPECFG (Pipe configuration)"},
{.address = 0xA4D8006A, .name = "PIPEBUF (Pipe buffer setting)"},
{.address = 0xA4D8006C, .name = "PIPEMAXP (Pipe max packet size)"},
{.address = 0xA4D8006E, .name = "PIPEPERI (Pipe cycle control)"},
{.address = 0xA4D80070, .name = "PIPE1CTR (Pipe 1 control)"},
{.address = 0xA4D80072, .name = "PIPE2CTR (Pipe 2 control)"},
{.address = 0xA4D80074, .name = "PIPE3CTR (Pipe 3 control)"},
{.address = 0xA4D80076, .name = "PIPE4CTR (Pipe 4 control)"},
{.address = 0xA4D80078, .name = "PIPE5CTR (Pipe 5 control)"},
{.address = 0xA4D8007A, .name = "PIPE6CTR (Pipe 6 control)"},
{.address = 0xA4D8007C, .name = "PIPE7CTR (Pipe 7 control)"},
{.address = 0xA4D8007E, .name = "PIPE8CTR (Pipe 8 control)"},
{.address = 0xA4D80080, .name = "PIPE9CTR (Pipe 9 control)"},
{.address = 0xA4D80090, .name = "PIPE1TRE (Pipe 1 transaction counter enable)"},
{.address = 0xA4D80092, .name = "PIPE1TRN (Pipe 1 transaction counter)"},
{.address = 0xA4D80094, .name = "PIPE2TRE (Pipe 2 transaction counter enable)"},
{.address = 0xA4D80096, .name = "PIPE2TRN (Pipe 2 transaction counter)"},
{.address = 0xA4D80098, .name = "PIPE3TRE (Pipe 3 transaction counter enable)"},
{.address = 0xA4D8009A, .name = "PIPE3TRN (Pipe 3 transaction counter)"},
{.address = 0xA4D8009C, .name = "PIPE4TRE (Pipe 4 transaction counter enable)"},
{.address = 0xA4D8009E, .name = "PIPE4TRN (Pipe 4 transaction counter)"},
{.address = 0xA4D800A0, .name = "PIPE5TRE (Pipe 5 transaction counter enable)"},
{.address = 0xA4D800A2, .name = "PIPE5TRN (Pipe 5 transaction counter)"},
{.address = 0xA40501D4, .name = "UPONCR (USB power control)"},
// FSI (FIFO serial interface)"},
{.address = 0xFE3C0000, .name = "A_DO_FMT (A output serial format)"},
{.address = 0xFE3C0004, .name = "A_DOFF_CTL (A output FIFO control)"},
{.address = 0xFE3C0008, .name = "A_DOFF_ST (A output FIFO status)"},
{.address = 0xFE3C000C, .name = "A_DI_FMT (A input serial format)"},
{.address = 0xFE3C0010, .name = "A_DIFF_CTL (A input FIFO control)"},
{.address = 0xFE3C0014, .name = "A_DIFF_ST (A input FIFO status)"},
{.address = 0xFE3C0018, .name = "A_CKG1 (A clock set 1)"},
{.address = 0xFE3C001C, .name = "A_CKG2 (A clock set 2)"},
{.address = 0xFE3C0020, .name = "A_DIDT (A read data)"},
{.address = 0xFE3C0024, .name = "A_DODT (A write data)"},
{.address = 0xFE3C0028, .name = "A_MUTE_ST (A mute state)"},
{.address = 0xFE3C0040, .name = "B_DO_FMT (B output serial format)"},
{.address = 0xFE3C0044, .name = "B_DOFF_CTL (B output FIFO control)"},
{.address = 0xFE3C0048, .name = "B_DOFF_ST (B output FIFO status)"},
{.address = 0xFE3C004C, .name = "B_DI_FMT (B input serial format)"},
{.address = 0xFE3C0050, .name = "B_DIFF_CTL (B input FIFO control)"},
{.address = 0xFE3C0054, .name = "B_DIFF_ST (B input FIFO status)"},
{.address = 0xFE3C0058, .name = "B_CKG1 (B clock set 1)"},
{.address = 0xFE3C005C, .name = "B_CKG2 (B clock set 2)"},
{.address = 0xFE3C0060, .name = "B_DIDT (B read data)"},
{.address = 0xFE3C0064, .name = "B_DODT (B write data)"},
{.address = 0xFE3C0068, .name = "B_MUTE_ST (B mute state)"},
{.address = 0xFE3C0200, .name = "INT_ST (Interrupt state)"},
{.address = 0xFE3C0204, .name = "IEMSK (Interrupt source mask)"},
{.address = 0xFE3C0208, .name = "IMSK (Interrupt signal mask)"},
{.address = 0xFE3C020C, .name = "MUTE (Mute set)"},
{.address = 0xFE3C0210, .name = "CLK_RST (Clock reset)"},
{.address = 0xFE3C0214, .name = "SOFT_RST (Software reset)"},
{.address = 0xFE3C0218, .name = "FIFO_SZ (FIFO size)"},
// KEY (Key interface unit)"},
{.address = 0xA44B0000, .name = "KIUDATA0 (Key input data 0)"},
{.address = 0xA44B0002, .name = "KIUDATA1 (Key input data 1)"},
{.address = 0xA44B0004, .name = "KIUDATA2 (Key input data 2)"},
{.address = 0xA44B0006, .name = "KIUDATA3 (Key input data 3)"},
{.address = 0xA44B0008, .name = "KIUDATA4 (Key input data 4)"},
{.address = 0xA44B000A, .name = "KIUDATA5 (Key input data 5)"},
{.address = 0xA44B000C, .name = "KIUCNTREG (Scan control)"},
{.address = 0xA44B000E, .name = "KIAUTOFIXREG (Automatic key bounce setting)"},
{.address = 0xA44B0010, .name = "KIUMODEREG (Scan mode setting)"},
{.address = 0xA44B0012, .name = "KIUSTATEREG (Scan state)"},
{.address = 0xA44B0014, .name = "KIUINTREG (Interrupt setting)"},
{.address = 0xA44B0016, .name = "KIUWSETREG (Scan wait time setting)"},
{.address = 0xA44B0018, .name = "KIUINTERVALREG (Scan interval time setting)"},
{.address = 0xA44B001A, .name = "KOUTPINSET (KOUT line function setting)"},
{.address = 0xA44B001C, .name = "KINPINSET (KIN line function setting)"},
// MSIOF0 (Sync serial interface 0)"},
{.address = 0xA4C40000, .name = "SITMDR1 (Transmit mode 1)"},
{.address = 0xA4C40004, .name = "SITMDR2 (Transmit mode 2)"},
{.address = 0xA4C40008, .name = "SITMDR3 (Transmit mode 3)"},
{.address = 0xA4C40020, .name = "SITSCR (Transmit clock select)"},
{.address = 0xA4C40010, .name = "SIRMDR1 (Receive mode 1)"},
{.address = 0xA4C40014, .name = "SIRMDR2 (Receive mode 2)"},
{.address = 0xA4C40018, .name = "SIRMDR3 (Receive mode 3)"},
{.address = 0xA4C40024, .name = "SIRSCR (Receive clock select)"},
{.address = 0xA4C40028, .name = "SICTR (Control)"},
{.address = 0xA4C40030, .name = "SIFCTR (FIFO control)"},
{.address = 0xA4C40040, .name = "SISTR (Status)"},
{.address = 0xA4C40044, .name = "SIIER (Interrupt enable)"},
{.address = 0xA4C40048, .name = "SITDR1 (Transmit control data 1)"},
{.address = 0xA4C4004C, .name = "SITDR2 (Transmit control data 2)"},
{.address = 0xA4C40050, .name = "SITFDR (Transmit FIFO data)"},
{.address = 0xA4C40058, .name = "SIRDR1 (Receive control data 1)"},
{.address = 0xA4C4005C, .name = "SIRDR2 (Receive control data 2)"},
{.address = 0xA4C40060, .name = "SIRFDR (Receive FIFO data)"},
// MSIOF1 (Sync serial interface 1)"},
{.address = 0xA4C50000, .name = "SITMDR1 (Transmit mode 1)"},
{.address = 0xA4C50004, .name = "SITMDR2 (Transmit mode 2)"},
{.address = 0xA4C50008, .name = "SITMDR3 (Transmit mode 3)"},
{.address = 0xA4C50020, .name = "SITSCR (Transmit clock select)"},
{.address = 0xA4C50010, .name = "SIRMDR1 (Receive mode 1)"},
{.address = 0xA4C50014, .name = "SIRMDR2 (Receive mode 2)"},
{.address = 0xA4C50018, .name = "SIRMDR3 (Receive mode 3)"},
{.address = 0xA4C50024, .name = "SIRSCR (Receive clock select)"},
{.address = 0xA4C50028, .name = "SICTR (Control)"},
{.address = 0xA4C50030, .name = "SIFCTR (FIFO control)"},
{.address = 0xA4C50040, .name = "SISTR (Status)"},
{.address = 0xA4C50044, .name = "SIIER (Interrupt enable)"},
{.address = 0xA4C50048, .name = "SITDR1 (Transmit control data 1)"},
{.address = 0xA4C5004C, .name = "SITDR2 (Transmit control data 2)"},
{.address = 0xA4C50050, .name = "SITFDR (Transmit FIFO data)"},
{.address = 0xA4C50058, .name = "SIRDR1 (Receive control data 1)"},
{.address = 0xA4C5005C, .name = "SIRDR2 (Receive control data 2)"},
{.address = 0xA4C50060, .name = "SIRFDR (Receive FIFO data)"},
// ADC (Analog/Digital converter)"},
{.address = 0xA4610080, .name = "ADDRA (A/D A data)"},
{.address = 0xA4610082, .name = "ADDRB (A/D B data)"},
{.address = 0xA4610084, .name = "ADDRC (A/D C data)"},
{.address = 0xA4610086, .name = "ADDRD (A/D D data)"},
{.address = 0xA4610088, .name = "ADCSR (A/D Control/status)"},
{.address = 0xA461008A, .name = "ADCCSR (A/D Custom control)"},
{.address = 0xA461008C, .name = "ADCUST (A/D Control)"},
{.address = 0xA461008E, .name = "ADPCTL (A/D Port control)"},
// SHway (Super Hyway Bus)"},
{.address = 0xFF800018, .name = "PRLCKCR (LCK control)"},
{.address = 0xFF800020, .name = "PRPRICR0 (PRI control 0)"},
{.address = 0xFF800028, .name = "PRPRICR1 (PRI control 1)"},
{.address = 0xFF800030, .name = "PRPRICR2 (PRI control 2)"},
{.address = 0xFF800038, .name = "PRPRICR3 (PRI control 3)"},
{.address = 0xFF800040, .name = "PRPRICR4 (PRI control 4)"},
{.address = 0xFF800048, .name = "PRPRICR5 (PRI control 5)"},
{.address = 0xA4530000, .name = "SHOCMCR (SHOC master control)"},
{.address = 0xA4530004, .name = "SHOCMSR (SHOC master status)"},
// stop
{.address = 0x00000000, .name = NULL},
};

View File

@ -0,0 +1,112 @@
#include <kernel/util/disasm.h>
#include <kernel/devices/earlyterm.h>
#include <kernel/drivers/screen.h>
#include <display.h>
#include <stdio.h>
#include <string.h>
// Menu string format.
// TODO: FIND BETTER WAY TROUDUC'
const char *content_string[26] = {
"General registers:",
"r0 = %#.8x",
"r1 = %#.8x",
"r2 = %#.8x",
"r3 = %#.8x",
"r4 = %#.8x",
"r5 = %#.8x",
"r6 = %#.8x",
"r7 = %#.8x",
"r8 = %#.8x",
"r9 = %#.8x",
"r10 = %#.8x",
"r11 = %#.8x",
"r12 = %#.8x",
"r13 = %#.8x",
"r14 = %#.8x",
"r15 = %#.8x",
"\0",
"Special registers:",
"GBR = %p",
"MACL = %p",
"MACH = %p",
"SR = %p",
"PC = %p",
"PR = %p",
NULL
};
static void cursor_update(ubc_session_t *session)
{
extern struct earlyterm earlyterm;
if (session->key.up == 1 && session->menu.context.cursor > 0)
session->menu.context.cursor = session->menu.context.cursor - 1;
if (session->key.down == 1
&& (int)session->menu.context.cursor < 24 - earlyterm.display.ws_row)
session->menu.context.cursor = session->menu.context.cursor + 1;
}
//
// 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 disasm_menu_show_context(ubc_session_t *session)
{
extern struct earlyterm earlyterm;
char line[64];
// Menu string data
uint32_t content_data[25] = {
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,
session->context->gbr,
session->context->macl,
session->context->mach,
session->context->ssr,
session->context->spc,
session->context->pr
};
// Update cursor position.
cursor_update(session);
// Clear VRAM.
dclear(&earlyterm.display);
// Display menu based on cursor position.
memset(line, 0x00, 64);
for (int i = 0 ; content_string[i + session->menu.context.cursor] != NULL
&& i < earlyterm.display.ws_row ; ++i)
{
sprintf(line,
content_string[i + session->menu.context.cursor],
content_data[i + session->menu.context.cursor]
);
dprint(&earlyterm.display, 0, i, line);
}
// Display VRAM
screen_update(earlyterm.display.vram);
}

View File

@ -0,0 +1,511 @@
#include <kernel/util/disasm.h>
#include <stdio.h>
const char *disasm_check_syscalls(uint32_t argument)
{
extern const struct sysname_s sh7305_syscalls[];
static char buffer[64];
const char *sysname;
uint32_t *systab;
// @note:
// Casio doesn't use the TRAPA instruction (software interruption), for switch from
// user mode to privileged mode. They just jump always at 0x80010070 and use the
// table of syscall addresses to redirect the jump. (and the table address is always
// stored at 0x8001007c).
systab = (uint32_t *)(ptrdiff_t)(*(uint32_t *)0x8001007c);
// Try to find the syscall name
sysname = "unknown";
for (uint32_t i = 0 ; i < 0x1000 ; ++i) {
if (systab[i] != argument)
continue;
for (int j = 0 ; sh7305_syscalls[j].name != NULL ; ++j) {
if (sh7305_syscalls[j].syscall == i) {
sysname = sh7305_syscalls[j].name;
break;
}
}
sprintf(buffer, "%%0x%.4x %s", i, sysname);
return (buffer);
}
return (NULL);
}
const struct sysname_s sh7305_syscalls[] = {
//
// Simon Lothar"},
//
{.syscall = 0x001, .name = "vbr_tlb_error"},
{.syscall = 0x002, .name = "vbr_cpu_address"},
{.syscall = 0x003, .name = "vbr_tlb_exception"},
{.syscall = 0x005, .name = "App_RegisterAddins"},
{.syscall = 0x009, .name = "App_FindFreeAddinSlot"},
{.syscall = 0x00a, .name = "App_GetAddinHeaderAddr"},
{.syscall = 0x00e, .name = "App_GetAddindEstrip"},
{.syscall = 0x013, .name = "GlibAddinAplExecutionCheck"},
{.syscall = 0x014, .name = "GlibGetAddinLibInfo"},
{.syscall = 0x015, .name = "GlibGetOSVersionInfo"},
{.syscall = 0x018, .name = "MMU_FlushCache"},
{.syscall = 0x01b, .name = "T6K11_Clear"},
{.syscall = 0x01c, .name = "Bdisp_WriteGraph_VRAM"},
{.syscall = 0x01d, .name = "Bdisp_WriteGraph_DD"},
{.syscall = 0x01e, .name = "Bdisp_WriteGraph_DDVRAM"},
{.syscall = 0x022, .name = "Bdisp_ReadArea_VRAM"},
{.syscall = 0x023, .name = "Bdisp_ReadArea_DD"},
{.syscall = 0x024, .name = "Bdisp_GetDisp_DD"},
{.syscall = 0x025, .name = "T6K11_ReadCurrentPage"},
{.syscall = 0x026, .name = "T6K11_ReadPage"},
{.syscall = 0x027, .name = "T6K11_WritePage"},
{.syscall = 0x028, .name = "Bdisp_PutDisp_DD"},
{.syscall = 0x02a, .name = "Bdisp_DrawShapeToVRAM"},
{.syscall = 0x02f, .name = "Bdisp_DrawShapeToVRAM"},
{.syscall = 0x030, .name = "Bdisp_DrawLineVRAM"},
{.syscall = 0x031, .name = "Bdisp_ClearLineVRAM"},
{.syscall = 0x032, .name = "Bdisp_DrawShapeToDD"},
{.syscall = 0x033, .name = "Bdisp_DrawShapeToVRAM_DD"},
{.syscall = 0x034, .name = "Bdisp_DrawShapeToDD"},
{.syscall = 0x035, .name = "Bdisp_DrawShapeToVRAM_DD"},
{.syscall = 0x039, .name = "RTC_Reset"},
{.syscall = 0x03a, .name = "RTC_GetTime"},
{.syscall = 0x03b, .name = "RTC_GetTicks"},
{.syscall = 0x03c, .name = "RTC_Elapsed_ms"},
{.syscall = 0x05c, .name = "Num_UIntToBCD"},
{.syscall = 0x05d, .name = "Num_BCDToUInt"},
{.syscall = 0x118, .name = "Timer_Install"},
{.syscall = 0x119, .name = "Timer_Deinstall"},
{.syscall = 0x11a, .name = "Timer_Start"},
{.syscall = 0x11b, .name = "Timer_Stop"},
{.syscall = 0x11f, .name = "Bdisp_PutDispArea_DD"},
{.syscall = 0x12d, .name = "DD_Poweroff"},
{.syscall = 0x130, .name = "Wait_ms"},
{.syscall = 0x132, .name = "DD_SetContrast"},
{.syscall = 0x133, .name = "DD_SetFRS"},
{.syscall = 0x134, .name = "DD_SetBias"},
{.syscall = 0x135, .name = "GetVRAMAddress"},
{.syscall = 0x136, .name = "GetCharacterGlyph"},
{.syscall = 0x137, .name = "GetCharacterMiniGlyph"},
{.syscall = 0x138, .name = "Cursor_SetPosition"},
{.syscall = 0x139, .name = "Cursor_SetFlashStyle"},
{.syscall = 0x13a, .name = "Cursor_SetFlashMode"},
{.syscall = 0x13b, .name = "Cursor_GetSettings"},
{.syscall = 0x13c, .name = "Print_OS"},
{.syscall = 0x142, .name = "Bdisp_AllClr_DD"},
{.syscall = 0x143, .name = "Bdisp_AllClr_VRAM"},
{.syscall = 0x144, .name = "Bdisp_AllClr_DDVRAM"},
{.syscall = 0x145, .name = "Bdisp_GetDisp_VRAM"},
{.syscall = 0x146, .name = "Bdisp_SetPoint_VRAM"},
{.syscall = 0x147, .name = "Bdisp_SetPoint_DD"},
{.syscall = 0x148, .name = "Bdisp_SetPoint_DDVRAM"},
{.syscall = 0x149, .name = "Bdisp_GetPoint_VRAM"},
{.syscall = 0x14a, .name = "Bdisp_AreaClr_DD"},
{.syscall = 0x14b, .name = "Bdisp_AreaClr_VRAM"},
{.syscall = 0x14c, .name = "Bdisp_AreaClr_DDVRAM"},
{.syscall = 0x14d, .name = "Bdisp_AreaReverseVRAM"},
{.syscall = 0x150, .name = "PrintXY"},
{.syscall = 0x153, .name = "Disp_Save"},
{.syscall = 0x154, .name = "Disp_Restore"},
{.syscall = 0x155, .name = "Disp_GetPtr"},
{.syscall = 0x156, .name = "PopUpWin"},
{.syscall = 0x158, .name = "Disp_Manage"},
{.syscall = 0x159, .name = "System_UpdateOS"},
{.syscall = 0x15d, .name = "PrintCR"},
{.syscall = 0x15f, .name = "atoi"},
{.syscall = 0x160, .name = "LongToAsc"},
{.syscall = 0x161, .name = "LongToAscHex"},
{.syscall = 0x162, .name = "pc_toupper"},
{.syscall = 0x163, .name = "pc_tolower"},
{.syscall = 0x172, .name = "strcmp"},
{.syscall = 0x173, .name = "strcmp"},
{.syscall = 0x175, .name = "some_datatable"},
{.syscall = 0x176, .name = "DiagnosticMode"},
{.syscall = 0x18a, .name = "InvertMem"},
{.syscall = 0x19f, .name = "SMEM_Optimization"},
{.syscall = 0x1a9, .name = "GUI_ProgressBar"},
{.syscall = 0x1b7, .name = "Get8x8BitmapPointer_1"},
{.syscall = 0x1b8, .name = "Get8x8BitmapPointer_2"},
{.syscall = 0x1b9, .name = "Get8x8BitmapPointer_3"},
{.syscall = 0x1ba, .name = "Get8x8BitmapPointer_4"},
{.syscall = 0x1bb, .name = "Get8x8BitmapPointer_5"},
{.syscall = 0x1bc, .name = "Get8x8BitmapPointer_6"},
{.syscall = 0x1bd, .name = "Get8x8BitmapPointer_7"},
{.syscall = 0x1e8, .name = "SMEM_OpenFile"},
{.syscall = 0x20e, .name = "StorageMemory_GetFilePos"},
{.syscall = 0x236, .name = "RebootOS"},
{.syscall = 0x23d, .name = "RTC_TriggerAlarm"},
{.syscall = 0x23e, .name = "RTC_SetDateTime"},
{.syscall = 0x241, .name = "Keyboard_ClrBuffer"},
{.syscall = 0x242, .name = "Bkey_Set_RepeatTime"},
{.syscall = 0x243, .name = "Bkey_Get_RepeatTime"},
{.syscall = 0x244, .name = "Bkey_Set_RepeatTime_Default"},
{.syscall = 0x245, .name = "Keyboard_EnableAutoRepeat"},
{.syscall = 0x246, .name = "Keyboard_DisableAutoRepeat"},
{.syscall = 0x247, .name = "Keyboard_GetKeyWait"},
{.syscall = 0x248, .name = "Keyboard_PutKeycode"},
{.syscall = 0x249, .name = "Keyboard_GetKeyDownTime"},
{.syscall = 0x24a, .name = "Keyboard_IsAnyKeyDown"},
{.syscall = 0x24b, .name = "Keyboard_IsSpecialKeyDown"},
{.syscall = 0x24c, .name = "Keyboard_IsSpecialKeyDown"},
{.syscall = 0x24d, .name = "Keyboard_KeyDown"},
{.syscall = 0x24e, .name = "Keyboard_SecondaryInterruptHandler"},
{.syscall = 0x24f, .name = "Keyboard_PutKeymatrixCode"},
{.syscall = 0x251, .name = "Keyboard_TimerHandler"},
{.syscall = 0x25e, .name = "Keyboard_PrimaryInterruptHandler"},
{.syscall = 0x268, .name = "GetFKeyIconPointer"},
{.syscall = 0x284, .name = "BCD_GetNaN"},
{.syscall = 0x285, .name = "Serial_Open_57600"},
{.syscall = 0x286, .name = "BCD_AnsToSerial"},
{.syscall = 0x28d, .name = "Comm_Open"},
{.syscall = 0x28e, .name = "Comm_Close"},
{.syscall = 0x28f, .name = "Comm_WaitForAnyBuffer"},
{.syscall = 0x290, .name = "Comm_ReadOneByte"},
{.syscall = 0x291, .name = "Comm_TransmitOneByte"},
{.syscall = 0x292, .name = "Comm_WaitForAndReadNBytes"},
{.syscall = 0x293, .name = "Comm_TransmitNBytes"},
{.syscall = 0x294, .name = "Comm_ClearReceiveBuffer"},
{.syscall = 0x295, .name = "Comm_ClearTransmitBuffer"},
{.syscall = 0x296, .name = "Comm_IsValidPacketAvailable"},
{.syscall = 0x298, .name = "Comm_IsOpen"},
{.syscall = 0x299, .name = "Comm_GetCurrentSelector"},
{.syscall = 0x2a1, .name = "HexToByte"},
{.syscall = 0x2a2, .name = "HexToWord"},
{.syscall = 0x2a3, .name = "ByteToHex"},
{.syscall = 0x2a4, .name = "WordToHex"},
{.syscall = 0x2a5, .name = "Comm_Padding_5C"},
{.syscall = 0x2a6, .name = "Comm_ReversePadding_5C"},
{.syscall = 0x2a7, .name = "AscHexToNibble"},
{.syscall = 0x2a8, .name = "NibbleToAscHex"},
{.syscall = 0x2a9, .name = "strlen"},
{.syscall = 0x2aa, .name = "slow_memcpy"},
{.syscall = 0x2ab, .name = "Serial_Open2"},
{.syscall = 0x2af, .name = "Comm_Spy0thByte"},
{.syscall = 0x2db, .name = "Comm_ProcessInPacket"},
{.syscall = 0x2e1, .name = "Comm_PrepareAckPacket"},
{.syscall = 0x2e2, .name = "Comm_PrepareErrorPacket"},
{.syscall = 0x2e3, .name = "Comm_PrepareTerminatePacket"},
{.syscall = 0x2e4, .name = "Comm_PrepareRoleswapPacket"},
{.syscall = 0x2e5, .name = "Comm_PrepareCheckPacket"},
{.syscall = 0x2e6, .name = "Comm_PrepareCommandPacket"},
{.syscall = 0x2e7, .name = "Comm_PrepareDataPacket"},
{.syscall = 0x2ee, .name = "System_GetOSVersion"},
{.syscall = 0x35e, .name = "memset_range"},
{.syscall = 0x35f, .name = "memset"},
{.syscall = 0x363, .name = "MCS_CreateDirectory"},
{.syscall = 0x364, .name = "MCS_WriteItem"},
{.syscall = 0x366, .name = "MCS_DeleteDirectory"},
{.syscall = 0x367, .name = "MCS_DeleteItem"},
{.syscall = 0x368, .name = "MCS_GetState"},
{.syscall = 0x369, .name = "MCS_GetSystemDirectoryInfo"},
{.syscall = 0x370, .name = "MCS_RenameItem"},
{.syscall = 0x371, .name = "MCS_OverwriteData"},
{.syscall = 0x372, .name = "MCS_GetItemData"},
{.syscall = 0x373, .name = "MCS_RenameDirectory"},
{.syscall = 0x374, .name = "BMCSRenameVariable"},
{.syscall = 0x375, .name = "MCS_SearchDirectory"},
{.syscall = 0x376, .name = "MCS_SearchDirectoryItem"},
{.syscall = 0x37c, .name = "MCS_GetFirstDataPointerByDirno"},
{.syscall = 0x37d, .name = "MCS_GetDirectoryEntryByNumber"},
{.syscall = 0x37e, .name = "MCS_SearchItem"},
{.syscall = 0x37f, .name = "MCS_str8cpy"},
{.syscall = 0x380, .name = "MCS_GetDirectoryEntryAddress"},
{.syscall = 0x381, .name = "MCS_GetCurrentBottomAddress"},
{.syscall = 0x383, .name = "MCS_GetCapa"},
{.syscall = 0x392, .name = "MCS_GetMainMemoryStart"},
{.syscall = 0x3dc, .name = "Setup_GetInfo"},
{.syscall = 0x3ea, .name = "SYSCALL_3ea_DATATABLE"},
{.syscall = 0x3ed, .name = "Interrupt_SetOrClrStatusFlags"},
{.syscall = 0x3ee, .name = "Interrupt_QueryStatusFlags"},
{.syscall = 0x3f4, .name = "PowerOff"},
{.syscall = 0x3f5, .name = "ClearMainMemory"},
{.syscall = 0x3f6, .name = "SH7337_TMU_Stop"},
{.syscall = 0x3f7, .name = "SH7337_TMU_int_handler"},
{.syscall = 0x3fa, .name = "Hmem_SetMMU"},
{.syscall = 0x3fb, .name = "MMU_ConfigureAndFlush"},
{.syscall = 0x3fc, .name = "TLB_SetAddressValue"},
{.syscall = 0x3fe, .name = "GetStackPtr"},
{.syscall = 0x3ff, .name = "MMU_FlushCache"},
{.syscall = 0x400, .name = "MMU_ConfigureAndEnable"},
{.syscall = 0x404, .name = "GetPhysicalROMstart"},
{.syscall = 0x405, .name = "GetPhysicalRAMstart"},
{.syscall = 0x409, .name = "Serial_ResetAndDisable"},
{.syscall = 0x40a, .name = "Serial_GetInterruptHandler"},
{.syscall = 0x40b, .name = "Serial_SetInterruptHandler"},
{.syscall = 0x40c, .name = "Serial_ReadOneByte"},
{.syscall = 0x40d, .name = "Serial_ReadNBytes"},
{.syscall = 0x40e, .name = "Serial_BufferedTransmitOneByte"},
{.syscall = 0x40f, .name = "Serial_BufferedTransmitNBytes"},
{.syscall = 0x410, .name = "Serial_DirectTransmitOneByte"},
{.syscall = 0x411, .name = "Serial_GetReceivedBytesAvailable"},
{.syscall = 0x412, .name = "Serial_GetFreeTransmitSpace"},
{.syscall = 0x413, .name = "Serial_ClearReceiveBuffer"},
{.syscall = 0x414, .name = "Serial_ClearTransmitBuffer"},
{.syscall = 0x418, .name = "Serial_Open"},
{.syscall = 0x419, .name = "Serial_Close"},
{.syscall = 0x41b, .name = "Serial_CallReceiveIntErrorResetHandler"},
{.syscall = 0x41c, .name = "Serial_CallReceiveIntHandler"},
{.syscall = 0x41d, .name = "Serial_CallTransmitIntErrorResetHandler"},
{.syscall = 0x41e, .name = "Serial_CallTransmitIntHandler"},
{.syscall = 0x420, .name = "OS_inner_Sleep"},
{.syscall = 0x422, .name = "Serial_SpyNthByte"},
{.syscall = 0x423, .name = "Serial_GetStatus"},
{.syscall = 0x425, .name = "Serial_IsOpen"},
{.syscall = 0x429, .name = "Bfile_identify_device_OS"},
{.syscall = 0x42c, .name = "Bfile_OpenFile_OS"},
{.syscall = 0x42d, .name = "Bfile_CloseFile_OS"},
{.syscall = 0x42e, .name = "Bfile_GetMediaFree_OS"},
{.syscall = 0x42f, .name = "Bfile_GetFileSize_OS"},
{.syscall = 0x431, .name = "Bfile_SeekFile_OS"},
{.syscall = 0x432, .name = "Bfile_ReadFile_OS"},
{.syscall = 0x434, .name = "Bfile_CreateEntry_OS"},
{.syscall = 0x435, .name = "Bfile_WriteFile_OS"},
{.syscall = 0x438, .name = "Bfile_RenameEntry"},
{.syscall = 0x439, .name = "Bfile_DeleteEntry"},
{.syscall = 0x43b, .name = "Bfile_FindFirst"},
{.syscall = 0x43c, .name = "Bfile_FindNext"},
{.syscall = 0x43d, .name = "Bfile_FindClose"},
{.syscall = 0x44e, .name = "memcpy"},
{.syscall = 0x44f, .name = "memcmp"},
{.syscall = 0x450, .name = "Bfile_GetFilenameLength"},
{.syscall = 0x451, .name = "Bfile_Name_cmp"},
{.syscall = 0x452, .name = "Bfile_Name_cpy"},
{.syscall = 0x453, .name = "Bfile_Name_ncpy"},
{.syscall = 0x456, .name = "Bfile_NameToStr_ncpy"},
{.syscall = 0x457, .name = "Bfile_StrToName_ncpy"},
{.syscall = 0x462, .name = "GetAppName"},
{.syscall = 0x463, .name = "SetAppName"},
{.syscall = 0x464, .name = "CmpAppName"},
{.syscall = 0x465, .name = "GetIntPtrContent"},
{.syscall = 0x467, .name = "LongToAscHex"},
{.syscall = 0x468, .name = "hasSDOption"},
{.syscall = 0x469, .name = "Battery_DisplayLowStatus"},
{.syscall = 0x46b, .name = "App_BuiltInCount"},
{.syscall = 0x476, .name = "Battery_IsLow"},
{.syscall = 0x477, .name = "EnableGetkeyToMainFunctionReturn"},
{.syscall = 0x478, .name = "DisableGetkeyToMainFunctionReturn"},
{.syscall = 0x47f, .name = "SetAutoPowerOffTime"},
{.syscall = 0x480, .name = "GetAutoPowerOffTime"},
{.syscall = 0x486, .name = "GetdatatablePtr"},
{.syscall = 0x48d, .name = "SetAutoPowerOffFlag"},
{.syscall = 0x48e, .name = "GetAutoPowerOffFlag"},
{.syscall = 0x492, .name = "Battery_IsLow"},
{.syscall = 0x494, .name = "CallbackAtQuitMainFunction"},
{.syscall = 0x495, .name = "Battery_DisplayLowStatus"},
{.syscall = 0x499, .name = "Heap_SetTopChunk"},
{.syscall = 0x49a, .name = "App_Start"},
{.syscall = 0x49c, .name = "Battery_GetStatus"},
{.syscall = 0x49e, .name = "RebootOS"},
{.syscall = 0x4a0, .name = "AUX_DisplayErrorMessage"},
{.syscall = 0x4ad, .name = "USB_InterruptHandler"},
{.syscall = 0x4ae, .name = "USB_TimerHandler"},
{.syscall = 0x4b0, .name = "AUX_DisplayFKeyIcons"},
{.syscall = 0x4cb, .name = "Keyboard_RemapFKeyCode"},
{.syscall = 0x4d1, .name = "AUX_DisplayFKeyIcon"},
{.syscall = 0x4dc, .name = "Setup_GetEntry"},
{.syscall = 0x4dd, .name = "Setup_SetEntry"},
{.syscall = 0x4de, .name = "Setup_GetEntryPtr"},
{.syscall = 0x4df, .name = "Alpha_GetData"},
{.syscall = 0x4e0, .name = "Alpha_SetData"},
{.syscall = 0x4e1, .name = "Alpha_ClearAll"},
{.syscall = 0x4e6, .name = "HourGlass"},
{.syscall = 0x4e9, .name = "LocalizeStringID"},
{.syscall = 0x4f5, .name = "BCD_ToStrAsNumber1"},
{.syscall = 0x4f6, .name = "BCD_ToStrAsNumber2"},
{.syscall = 0x500, .name = "BCDToInternal"},
{.syscall = 0x518, .name = "Setup_GetEntry_3E"},
{.syscall = 0x519, .name = "Setup_GetEntry_40"},
{.syscall = 0x51a, .name = "Setup_SetEntry_3E"},
{.syscall = 0x51b, .name = "Setup_SetEntry_40"},
{.syscall = 0x531, .name = "MB_IsLead"},
{.syscall = 0x533, .name = "MB_ElementCount"},
{.syscall = 0x534, .name = "MB_ByteCount"},
{.syscall = 0x536, .name = "MB_strcat"},
{.syscall = 0x537, .name = "MB_strncat"},
{.syscall = 0x538, .name = "MB_strcpy"},
{.syscall = 0x53c, .name = "MB_GetSecondElemPtr"},
{.syscall = 0x53d, .name = "MB_GetElement"},
{.syscall = 0x53e, .name = "MB_CopyToHeap"},
{.syscall = 0x53f, .name = "memcmp"},
{.syscall = 0x541, .name = "itoa"},
{.syscall = 0x542, .name = "to_uppercase"},
{.syscall = 0x543, .name = "to_lowercase"},
{.syscall = 0x544, .name = "BCD_0"},
{.syscall = 0x545, .name = "BCD_1"},
{.syscall = 0x546, .name = "BCD_2"},
{.syscall = 0x547, .name = "BCD_10"},
{.syscall = 0x548, .name = "BCD_1_over_3"},
{.syscall = 0x549, .name = "BCD_0.5"},
{.syscall = 0x54a, .name = "BCD_32767"},
{.syscall = 0x54b, .name = "BCD_m32768"},
{.syscall = 0x54c, .name = "BCD_65536"},
{.syscall = 0x54d, .name = "BCD_0x7fffffff"},
{.syscall = 0x54e, .name = "BCD_m2Gi"},
{.syscall = 0x54f, .name = "BCD_4Gi"},
{.syscall = 0x550, .name = "BCD_pi"},
{.syscall = 0x551, .name = "BCD_2pi"},
{.syscall = 0x552, .name = "BCD_pi_over_2"},
{.syscall = 0x553, .name = "BCD_e"},
{.syscall = 0x554, .name = "BCD_5"},
{.syscall = 0x5a6, .name = "BCD_SetAsInt"},
{.syscall = 0x5af, .name = "BCD_pi_over_4"},
{.syscall = 0x5b0, .name = "BCD_ln10"},
{.syscall = 0x5b1, .name = "BCD_ln2"},
{.syscall = 0x5b2, .name = "BCD_9.99e99"},
{.syscall = 0x5b3, .name = "BCD_m9.99e99"},
{.syscall = 0x5b4, .name = "BCD_9.99999999999999e99"},
{.syscall = 0x5b5, .name = "BCD_227.85"},
{.syscall = 0x5b6, .name = "BCD_sqrt2"},
{.syscall = 0x5b7, .name = "BCD_sqrt2_over_2"},
{.syscall = 0x5b8, .name = "BCD_506.6282746310"},
{.syscall = 0x645, .name = "CalculateExpression"},
{.syscall = 0x64a, .name = "CalculateExpression0"},
{.syscall = 0x652, .name = "PRGM_NextOpcode"},
{.syscall = 0x6a6, .name = "PRGM_IsEndOfLine"},
{.syscall = 0x6c4, .name = "Keyboard_PRGM_GetKey"},
{.syscall = 0x6d4, .name = "Alpha_GetData2"},
{.syscall = 0x713, .name = "Print_ClearLine"},
{.syscall = 0x763, .name = "Bdisp_DrawRectangle"},
{.syscall = 0x7fc, .name = "OpcodeToStr"},
{.syscall = 0x804, .name = "CLIP_Store"},
{.syscall = 0x807, .name = "locate"},
{.syscall = 0x808, .name = "Print"},
{.syscall = 0x809, .name = "PrintRev"},
{.syscall = 0x80a, .name = "PrintC"},
{.syscall = 0x80b, .name = "PrintRevC"},
{.syscall = 0x80c, .name = "PrintLine"},
{.syscall = 0x80d, .name = "PrintRLine"},
{.syscall = 0x80e, .name = "Cursor_GetFlashStyle"},
{.syscall = 0x80f, .name = "Cursor_GetSettings"},
{.syscall = 0x811, .name = "Cursor_SetFlashOn"},
{.syscall = 0x812, .name = "Cursor_SetFlashOff"},
{.syscall = 0x813, .name = "SaveDisp"},
{.syscall = 0x814, .name = "RestoreDisp"},
{.syscall = 0x829, .name = "MCS_CreateDirectory"},
{.syscall = 0x82a, .name = "MCS_PutInternalItem"},
{.syscall = 0x82b, .name = "MCSPutVar2"},
{.syscall = 0x830, .name = "MCSOvwDat2"},
{.syscall = 0x832, .name = "MCS_OverwriteOpenItem"},
{.syscall = 0x833, .name = "MCS_ClearInternalDirectory"},
{.syscall = 0x834, .name = "MCS_ClearDirectory"},
{.syscall = 0x835, .name = "MCS_DeleteInternalItem"},
{.syscall = 0x836, .name = "MCSDelVar2"},
{.syscall = 0x83a, .name = "MCS_GotoInternalItem"},
{.syscall = 0x83b, .name = "MCS_OpenMainMemoryItem"},
{.syscall = 0x83c, .name = "MCS_GotoHandleNeighbour"},
{.syscall = 0x83d, .name = "MCS_CheckOpenedItem"},
{.syscall = 0x83e, .name = "MCS_GetOpenItem"},
{.syscall = 0x83f, .name = "MCS_OpenInternalDirectoryItem"},
{.syscall = 0x840, .name = "MCSGetDlen2"},
{.syscall = 0x841, .name = "MCSGetData1"},
{.syscall = 0x843, .name = "MCS_MapMCS_Result"},
{.syscall = 0x844, .name = "MCSGetCapa"},
{.syscall = 0x84d, .name = "MCS_OpenAlphaMemItem"},
{.syscall = 0x852, .name = "MCS_DirtypeToItemtype"},
{.syscall = 0x853, .name = "MCS_ItemtypeToDirtype"},
{.syscall = 0x863, .name = "MCS_DirtypeToName"},
{.syscall = 0x866, .name = "MCS_MapError"},
{.syscall = 0x869, .name = "Alpha_ClearAllAndAns"},
{.syscall = 0x86f, .name = "MCS_DeleteDirectoryItems"},
{.syscall = 0x8db, .name = "EditExpression"},
{.syscall = 0x8dc, .name = "EditValue"},
{.syscall = 0x8e6, .name = "EditMBStringCtrl"},
{.syscall = 0x8ea, .name = "DisplayMBString"},
{.syscall = 0x8ec, .name = "EditMBStringChar"},
{.syscall = 0x8f7, .name = "DisplayMBString2"},
{.syscall = 0x8fe, .name = "PopupWin"},
{.syscall = 0x901, .name = "DisplayMessageBox"},
{.syscall = 0x905, .name = "DisplayErrorMessage"},
{.syscall = 0x90b, .name = "SetShiftAlphaState"},
{.syscall = 0x90c, .name = "GetInsOverwriteState"},
{.syscall = 0x90d, .name = "SetInsOverwriteState"},
{.syscall = 0x90e, .name = "ClrShiftAlphaState"},
{.syscall = 0x90f, .name = "GetKey"},
{.syscall = 0x910, .name = "PutKey"},
{.syscall = 0x91b, .name = "GetShiftAlphaState"},
{.syscall = 0x924, .name = "TestMode"},
{.syscall = 0x954, .name = "DisplayErrorMessage"},
{.syscall = 0x985, .name = "App_CONICS"},
{.syscall = 0x998, .name = "App_DYNA"},
{.syscall = 0x9ad, .name = "PrintXY"},
{.syscall = 0x9df, .name = "App_EACT"},
{.syscall = 0x9e1, .name = "App_Equation"},
{.syscall = 0x9e2, .name = "App_EQUA"},
{.syscall = 0x9f5, .name = "App_Program"},
{.syscall = 0xa00, .name = "App_FINANCE"},
{.syscall = 0xa1f, .name = "Keyboard_RemapFKeyCode"},
{.syscall = 0xa35, .name = "AUX_DisplayMessage"},
{.syscall = 0xa48, .name = "App_GRAPH_TABLE"},
{.syscall = 0xa4a, .name = "App_LINK"},
{.syscall = 0xa6a, .name = "App_Optimization"},
{.syscall = 0xa6b, .name = "App_Memory"},
{.syscall = 0xa75, .name = "App_RECUR"},
{.syscall = 0xa97, .name = "App_RUN_MAT_EXE"},
{.syscall = 0xaae, .name = "App_RUN_MAT"},
{.syscall = 0xac6, .name = "App_STAT"},
{.syscall = 0xac8, .name = "App_SYSTEM"},
{.syscall = 0xacc, .name = "free"},
{.syscall = 0xacd, .name = "malloc"},
{.syscall = 0xace, .name = "memcmp"},
{.syscall = 0xacf, .name = "smart_memcpy"},
{.syscall = 0xad0, .name = "memset"},
{.syscall = 0xad4, .name = "strcat"},
{.syscall = 0xad5, .name = "smart_strcmp"},
{.syscall = 0xad6, .name = "strlen"},
{.syscall = 0xad7, .name = "strncat"},
{.syscall = 0xad8, .name = "strncmp"},
{.syscall = 0xad9, .name = "strncpy"},
{.syscall = 0xada, .name = "strrchr"},
{.syscall = 0xae8, .name = "CatalogDialog"},
{.syscall = 0xc4f, .name = "PrintMiniSd"},
{.syscall = 0xca7, .name = "OpcodeType"},
{.syscall = 0xcb0, .name = "Basic_Send_Send38k"},
{.syscall = 0xcb1, .name = "Basic_Receive_Receive38k"},
{.syscall = 0xcb2, .name = "Basic_OpenComPort38k_CloseComPort38k"},
{.syscall = 0xcc4, .name = "InputNumber"},
{.syscall = 0xcc5, .name = "InputString"},
{.syscall = 0xccb, .name = "GetRAMSize"},
{.syscall = 0xcd0, .name = "another_diagnostic_dialog"},
{.syscall = 0xd64, .name = "InputDateDialog"},
{.syscall = 0xd65, .name = "InputMonthDialog"},
{.syscall = 0xd66, .name = "InputDayDialog"},
{.syscall = 0xd67, .name = "InputYearDialog"},
{.syscall = 0xdab, .name = "StoreExpressionToGraphFuncMemory"},
{.syscall = 0xe6b, .name = "calloc"},
{.syscall = 0xe6c, .name = "memmove"},
{.syscall = 0xe6d, .name = "realloc"},
{.syscall = 0xe6e, .name = "strchr"},
{.syscall = 0xe6f, .name = "strstr"},
//
// LEPHE"},
//
{.syscall = 0x001, .name = "TLB_exception_handler (protection)"},
{.syscall = 0x001, .name = "TLB_exception_handler (protection)"},
{.syscall = 0x002, .name = "CPU address error handler (instruction/data)"},
{.syscall = 0x000, .name = "sys_init"},
{.syscall = 0x004, .name = "tlb_init"},
{.syscall = 0x3fc, .name = "tlb_map"},
{.syscall = 0xac9, .name = "longjmp"},
{.syscall = 0xaca, .name = "setjmp"},
//
// Stop
//
{.syscall = 0xfff, .name = NULL},
};

View File

@ -0,0 +1,13 @@
.text
.global _casio_syscall_test
_casio_syscall_test:
mov.l .syscall_entry, r1
mov.l .sys_getVRAM, r0
jmp @r1
nop
.align 4
.syscall_entry: .long 0x80010070
.sys_getVRAM: .long 0x00000135
.end

View File

@ -132,6 +132,7 @@ SECTIONS
. = ORIGIN(ilram);
.ubc ALIGN(4) : ALIGN(4) {
_bubc_rom = LOADADDR(.ubc) ;
_vhex_dbr = . ;
_bubc_ram = . ;
*(.ubc.handler)

20
src/lib/display/dhline.c Normal file
View File

@ -0,0 +1,20 @@
#include <display.h>
void dhline(display_t *disp, int x, int y, int width)
{
// Check error
if (y < 0 || y >= 64 || x >= 128)
return;
// culling
if (x < 0) {
width = width + x;
x = 0;
}
if (x + width > 128)
width = 128 - x;
// Draw line pixel per pixel x___x
for ( ; x < width ; ++x)
disp->vram[(x >> 5) + (y << 2)] |= 0x80000000 >> (x & 31);
}

View File

@ -9,11 +9,14 @@ int dopen(display_t *disp, const char *fontname)
disp->font = &default5x3;
// Display size is hardcoded for now
// TODO: hardware check !!!!
disp->display.width = 128;
disp->display.height = 64;
// Pre-calculate internal value used to draw
disp->nb_char_width = disp->font->bitmap.width + disp->font->bitmap.cwidth - 1;
disp->nb_char_width = disp->nb_char_width / disp->font->bitmap.cwidth;
disp->ws_col = disp->display.width / (disp->font->font.width + 1);
disp->ws_row = disp->display.height / (disp->font->font.height + 1);
return (0);
}

View File

@ -1,3 +1,40 @@
#include <display.h>
void dprint(display_t *disp, int col, int row, const char *format)
{
int scol;
scol = col;
for (int i = 0 ; format[i] != '\0' ; ++i)
{
// Check special char
if (format[i] == '\n') {
row = row + 1;
col = scol;
continue;
}
// Workaorund for disasm menu :E
if (format[i] == '\t') {
col = col + (4 - (i & 3));
continue;
}
// Check useless draw and display char
if (!(row < 0 || row >= disp->ws_row
|| col < 0 || col >= disp->ws_col)) {
dascii(disp, col, row, format[i], 0);
}
// Update horizontal cursor
col = col + 1;
}
}
//
// PRINTF LIKE (stopped)
//
/*#include <lib/display.h>
#include <stdarg.h>

View File

@ -2,14 +2,6 @@
void drect(display_t *disp, 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;
@ -22,36 +14,24 @@ void drect(display_t *disp, int x, int y, int width, int height)
// Get "real" Y position and area height.
if (y < 0)
{
height = height + x;
height = height + y;
y = 0;
} else {
if (y + height >= (int)disp->display.height)
height = disp->display.height - x;
height = disp->display.height - y;
}
// Check potential error.
// @note we do not check height because the while()
// while do the job for us.
if (width < 0)
if (width < 0 || height < 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;
// Draw the two horizontal lines
dhline(disp, x, y, width);
dhline(disp, x, y + height, width);
// Reverse area
while (--height >= 0)
{
j = width + x;
while (--j >= x)
{
disp->vram[(j >> 5) + vram_offset_y] &= ~(0x80000000 >> (j & 31));
}
vram_offset_y = vram_offset_y - 4;
}
// Draw th two vertical line
dvline(disp, x, y, height);
dvline(disp, x + width, y, height);
}

View File

@ -23,11 +23,11 @@ void dreverse(display_t *disp, int x, int y, int width, int height)
// Get "real" Y position and area height.
if (y < 0)
{
height = height + x;
height = height + y;
y = 0;
} else {
if (y + height >= (int)disp->display.height)
height = disp->display.height - x;
height = disp->display.height - y;
}
// Check potential error.

23
src/lib/display/dvline.c Normal file
View File

@ -0,0 +1,23 @@
#include <display.h>
void dvline(display_t *disp, int x, int y, int height)
{
// Check error
if (x < 0 || x >= 128 || y >= 64)
return;
// culling
if (y < 0) {
height = height + y;
y = 0;
}
if (y + height > 64)
height = 64 - y;
// get pixel mask
uint32_t pxmask = 0x80000000 >> (x & 31);
// Draw line pixel per pixel x___x
for ( ; y < height ; ++y)
disp->vram[(x >> 5) + (y << 2)] |= pxmask;
}

View File

@ -36,6 +36,8 @@ static void base_to_str(struct printf_opt *opt, uint64_t num, int base, int digi
static void disp_format(struct printf_opt *opt)
{
int total;
// display pre symbols
if (opt->sign != '\0')
(*opt->disp_char)(opt, opt->sign);
@ -44,15 +46,21 @@ static void disp_format(struct printf_opt *opt)
if (opt->base[1] != '\0')
(*opt->disp_char)(opt, opt->base[1]);
// padding
if (opt->flags.minus == 1 && opt->width > opt->digits)
// padding (left)
if ((opt->flags.minus == 1 || opt->flags.zero == 1) && opt->width > opt->digits)
{
int total = opt->digits + (opt->sign != '\0') +
(opt->base[0] != '\0') + (opt->base[1] != '\0');
total = opt->width - total;
total = opt->digits + (opt->sign != '\0') + (opt->base[0] != '\0') + (opt->base[1] != '\0');
total = opt->width - (total + opt->precision);
while (--total >= 0)
(*opt->disp_char)(opt, (opt->flags.zero == 1) ? '0' : ' ');
(*opt->disp_char)(opt, (opt->flags.minus == 1) ? ' ' : '0');
}
// Precision
if (opt->precision > opt->digits)
{
total = opt->precision - opt->digits;
while (--total >= 0)
(*opt->disp_char)(opt, '0');
}
// Display number
@ -60,8 +68,8 @@ static void disp_format(struct printf_opt *opt)
while (--opt->digits >= 0)
(*opt->disp_char)(opt, opt->format[opt->digits]);
// padding
if (opt->flags.minus == 0 && opt->width > saved_digits)
// padding (right)
if (opt->flags.minus == 0 && opt->flags.zero == 0 && opt->width > saved_digits)
{
int total = saved_digits + (opt->sign != '\0') +
(opt->base[0] != '\0') + (opt->base[1] != '\0');
@ -131,7 +139,7 @@ static void action_ptr(struct printf_opt *opt, char n)
opt->sign = '@';
opt->base[0] = '0';
opt->base[1] = 'x';
base_to_str(opt, (uint64_t)va_arg(opt->ap, void*), 16, 8);
base_to_str(opt, (uint32_t)va_arg(opt->ap, void*), 16, 8);
disp_format(opt);
}

View File

@ -47,6 +47,10 @@ static int get_width(struct printf_opt *opt, const char *restrict format)
static int get_precision(struct printf_opt *opt, const char *restrict format)
{
// Wipe old precision:w
//
opt->precision = 0;
// Check if precision is specified
if (format[0] != '.')
return (0);
@ -59,13 +63,8 @@ static int get_precision(struct printf_opt *opt, const char *restrict format)
// Get static precision
int i = 0;
opt->precision = 0;
while (format[++i] >= '0' && format[i] <= '9')
opt->precision = (opt->precision * 10) + (format[i] - '0');
// Check default precision
if (i == 0)
opt->precision = 1;
return (i);
}