vxkernel - v0.7.0-1 : fix linker script + update SDL2 keycode + add USB info

*add*
> [include/driver/sh7305/]
  | [usb] add USB hardware bitfields

*update*
> [display/draw]
  | [line] update all line-drawing prototype to `d*line(int color, ...)`
  | [rect] rename `drect_filled()` -> `drect()`
> [drivers/mpu/sdl2]
  | [keyboard] remove hardcoded number of translated key to facilitate update
  | [keyboard] add [0] to [9] keys support
  | [keyboard] change [SHIFT] and [ALPHA] key translation
  | [keyboard] proper use of `SDLK_*` macros for SDL2 key

*fix*
> [.nvimrc]
  | fix header file which are considered as a C++ file
> [boards/fxcg50]
  | [fxcg50.ld] switch tab to 4 spaces
  | [fxcg50.ld] proper inject `.got*` and `.data` sections in `userram`
  | [fxcg50.ld] isolate `.vhex.vbr` section before `.bss`
  | [fxcg50.ld] explicit that the `.bss` section should not be stored in ELF
  | [fxcg50.ld] isolate `.vhex.vbr` gaps in `.bss` section
  | [fxcg50.ld] do not inject `.xram` section in `userram`
> [display/draw]
  | [rect] fix missing header
This commit is contained in:
Yann MAGNIN 2023-01-22 18:39:43 +01:00
parent 7713e5e059
commit 5ea6e33f46
9 changed files with 700 additions and 212 deletions

View File

@ -2,8 +2,11 @@
" Setup GCC as linter
"let g:ale_linters = {'c' : ['sh-elf-vhex-gcc']}
" Patch include header
" Patch option
" @note
" - we setup cpp because header file is considered ad C++ file
let g:ale_c_cc_options = '-std=c11 -Wall -I./kernel/include -I./boards/*/include'
let g:ale_cpp_cc_options = '-std=c11 -Wall -I./kernel/include -I./boards/*/include'
" Enable completion
let g:ale_completion_enabled = 1

View File

@ -1,5 +1,5 @@
/*
Linker script for the fxcg50 platform.
Linker script for the fxcg50 platform.
*/
OUTPUT_FORMAT("elf32-sh", "elf32-sh", "elf32-sh")
@ -11,202 +11,207 @@ ENTRY(_initialize)
*/
MEMORY
{
/* virtual memory, read-write segment */
userram (WX) : o = 0x00000000, l = 1M
/* On-chip X memory */
xram (rwx): o = 0xe5007000, l = 8k
/* virtual memory, read-write segment */
userram (WX) : o = 0x00000000, l = 1M
/* On-chip X memory */
xram (rwx): o = 0xe5007000, l = 8k
}
SECTIONS
{
/* Code */
.text : {
PROVIDE(___kernel_reloc_start = .);
/* Code */
.text : {
PROVIDE(___kernel_reloc_start = .);
*(.text);
*(.text.*);
*(.text);
*(.text.*);
_bctors = . ;
*(.ctors .ctors.*)
_ectors = . ;
_bctors = . ;
*(.ctors .ctors.*)
_ectors = . ;
_bdtors = . ;
*(.dtors .dtors.*)
_edtors = . ;
_bdtors = . ;
*(.dtors .dtors.*)
_edtors = . ;
} > userram
} > userram
/* vhex's interrupt handler blocks (.vhex.blocks)
Although vhex's blocks end up in VBR space, they are relocated at
startup by the library/drivers, so we store them here for now */
.vhex.blocks : {
KEEP(*(.vhex.blocks));
} > userram
/* vhex's interrupt handler blocks (.vhex.blocks)
Although vhex's blocks end up in VBR space, they are relocated at
startup by the library/drivers, so we store them here for now */
.vhex.blocks : {
KEEP(*(.vhex.blocks));
} > userram
/* Exposed driver interfaces (.vhex.drivers)
The driver information is required to start and configure the
driver, even if the symbols are not referenced */
.vhex.drivers : {
_vhex_drivers_start = . ;
KEEP(*(SORT_BY_NAME(.vhex.drivers.*)));
_vhex_drivers_end = . ;
} > userram
/* Exposed driver interfaces (.vhex.drivers)
The driver information is required to start and configure the
driver, even if the symbols are not referenced */
.vhex.drivers : {
_vhex_drivers_start = . ;
KEEP(*(SORT_BY_NAME(.vhex.drivers.*)));
_vhex_drivers_end = . ;
} > userram
/* Exposed module interfaces (.vhex.modules) */
.vhex.modules : {
_vhex_modules_start = . ;
KEEP(*(SORT_BY_NAME(.vhex.modules.*)));
_vhex_modules_end = . ;
} > userram
/* Exposed module interfaces (.vhex.modules) */
.vhex.modules : {
_vhex_modules_start = . ;
KEEP(*(SORT_BY_NAME(.vhex.modules.*)));
_vhex_modules_end = . ;
} > userram
/* Exposed device interfaces (.vhex.device) */
.vhex.device : {
_vhex_devices_start = . ;
KEEP(*(.vhex.device));
_vhex_devices_end = . ;
} > userram
/* Exposed device interfaces (.vhex.device) */
.vhex.device : {
_vhex_devices_start = . ;
KEEP(*(.vhex.device));
_vhex_devices_end = . ;
} > userram
/* Read-only sections */
.rodata : {
/* Read-Only data */
*(.rodata);
*(.rodata.*);
} > userram
/* Read-only sections */
.rodata : {
/* Read-Only data */
*(.rodata);
*(.rodata.*);
} > userram
/* The GOT section is a bit exotic.
When I generate the PIE executable, all global variables are stored
is the *(.got) section and the __GLOBAL_OFFSET_TABLE__ object is
generated and inserted in the *(.got.plt) section.
/* The GOT section is a bit exotic.
When I generate the PIE executable, all global variables are stored
is the *(.got) section and the __GLOBAL_OFFSET_TABLE__ object is
generated and inserted in the *(.got.plt) section.
But, neither of *(.plt*) or *(rela*) section are generated to help
me out for the "relocation" of each address stored in the GOT. The
result is that the content of the GOT is always absolute addresses,
which makes the machine crash.
But, neither of *(.plt*) or *(rela*) section are generated to help
me out for the "relocation" of each address stored in the GOT. The
result is that the content of the GOT is always absolute addresses,
which makes the machine crash.
So, the idea to bypass this limitation (probably due to the custom
GCC which not provide critical information for the relocation) is to
isolate the GOT in a standalone section and, after the loading of
the image, walk thought the relocalised table and manually patch
each address.
So, the idea to bypass this limitation (probably due to the custom
GCC which not provide critical information for the relocation) is to
isolate the GOT in a standalone section and, after the loading of
the image, walk thought the relocalised table and manually patch
each address.
Moreover, the __GLOBAL_OFFSET_TABLE__ is used like a table, so, the
section ".got.plt" SHOULD be before the .got section. */
.got.plt : { *(.got.plt) *(.igot.plt) *(.igot) }
.got : { *(.got) }
Moreover, the __GLOBAL_OFFSET_TABLE__ is used like a table, so, the
section ".got.plt" SHOULD be before the .got section. */
.got.plt : { *(.got.plt) *(.igot.plt) *(.igot) } > userram
.got : { *(.got) } > userram
.dynamic : { *(.dynamic) }
.dynamic : { *(.dynamic) } > userram
/* readable / writable data */
.data ALIGN(4) : {
/* readable / writable data */
.data ALIGN(4) : {
/* Data sections */
*(.data);
*(.data.*);
*(COMMON);
}
/* Data sections */
*(.data);
*(.data.*);
} > userram
.bss ALIGN(4) : {
/* bss section included to avoid missaligned segment */
*(.bss);
*(.bss.*);
/* Vhex VBR management geometry
/* dynamic BSS information (move me ?) */
*(.dynbss)
Due to the SH3/SH4 VBR system, we have some restrictions:
/* Video RAM symbols
The handlers should reside at VBR relative position, in P1 or P2
protected space (0x8* or 0xA*). For our case, the bootloader will
relocalise the kernel at the P1 area using the Casio's UTLB
information. So, we don't have to wories about this here.
The Video RAM contains a full pixel sized frame for the
screen. Its size is 396x224 and each pixel depth is 16bits,
so (3996 * 224) * 2 = 177408
There are 3 vectors offset called by the processor : VBR + 0x100,
0x400 and 0x600. The first offset is involved when an exception
occur, the second when a memory (TLB) error is detected and the last
when an interruptions is detected.
Thus, we use a double buffering methods to speed-up the
render, this is why we define two VRAM */
All exception and memory interuption will be handled "normaly" : a
simple handler will be involved which will try to resolve/fix the
problem, if nothing can be fixed, a panic screen will be displayed.
_vhex_vram0 = ALIGN(32);
. = _vhex_vram0 + 177408;
_vhex_vram1 = ALIGN(32);
. = _vhex_vram1 + 177408;
However, regarding interuptions, we will use a power-full and
complexe technique to compact as most as possible the VBR size. To
explain the technique we need to know that each interruption start at
offset VBR + 0x600 and each interrupt source is "gapped" by 0x20 (
for exemple the 0x400 is for TMU0, 0x420 is for TMU1 and 0x440 is for
TMU2) Moreover, we have some "hole" in the "interrup map".
So, the idea is to write all interrupt handler in "blocks" of 32
bytes, and, for those that 32 bytes is to short, can use hole of the
interrupt map. */
.vhex.vbr : ALIGN(4) {
} > userram
_vhex_vbr = . - 0x100;
*(.vhex.exch.pretext) ;
*(.vhex.exch)
/* Vhex VBR management geometry
. = _vhex_vbr + 0x400;
*(.vhex.tlbh.pretext) ;
*(.vhex.tlbh) ;
Due to the SH3/SH4 VBR system, we have some restrictions:
. = _vhex_vbr + 0x600;
*(.vhex.inth.pretext) ;
*(.vhex.inth) ;
The handlers should reside at VBR relative position, in P1 or P2
protected space (0x8* or 0xA*). For our case, the bootloader will
relocalise the kernel at the P1 area using the Casio's UTLB
information. So, we don't have to wories about this here.
/* interrupt block entry */
__vhex_interrupth_start = ALIGN(4);
There are 3 vectors offset called by the processor : VBR + 0x100,
0x400 and 0x600. The first offset is involved when an exception
occur, the second when a memory (TLB) error is detected and the last
when an interruptions is detected.
All exception and memory interuption will be handled "normaly" : a
simple handler will be involved which will try to resolve/fix the
problem, if nothing can be fixed, a panic screen will be displayed.
} > userram
However, regarding interuptions, we will use a power-full and
complexe technique to compact as most as possible the VBR size. To
explain the technique we need to know that each interruption start at
offset VBR + 0x600 and each interrupt source is "gapped" by 0x20 (
for exemple the 0x400 is for TMU0, 0x420 is for TMU1 and 0x440 is for
TMU2) Moreover, we have some "hole" in the "interrup map".
So, the idea is to write all interrupt handler in "blocks" of 32
bytes, and, for those that 32 bytes is to short, can use hole of the
interrupt map. */
.vhex.vbr : ALIGN(4) {
.bss ALIGN(4) : {
_vhex_vbr = . - 0x100;
*(.vhex.exch.pretext) ;
*(.vhex.exch)
/* set some space (TODO explain) */
. = __vhex_interrupth_start + 4096;
. = _vhex_vbr + 0x400;
*(.vhex.tlbh.pretext) ;
*(.vhex.tlbh) ;
/* bss section included to avoid missaligned segment */
*(.bss);
*(.bss.*);
*(COMMON);
. = _vhex_vbr + 0x600;
*(.vhex.inth.pretext) ;
*(.vhex.inth) ;
/* dynamic BSS information (move me ?) */
*(.dynbss)
/* interrupt block entry */
__vhex_interrupth_start = ALIGN(4);
/* Video RAM symbols
/* static ram start (for kmalloc) */
PROVIDE(___sram_start = ALIGN(4) + 4096);
The Video RAM contains a full pixel sized frame for the
screen. Its size is 396x224 and each pixel depth is 16bits,
so (3996 * 224) * 2 = 177408
} > userram
Thus, we use a double buffering methods to speed-up the
render, this is why we define two VRAM */
/* On-chip memory sections: IL and Y (X is reserved) */
_vhex_vram0 = ALIGN(32);
. = _vhex_vram0 + 177408;
_vhex_vram1 = ALIGN(32);
. = _vhex_vram1 + 177408;
. = ORIGIN(xram);
.xram ALIGN(4) : ALIGN(4) {
/* static ram start (for kmalloc) */
___sram_start = ALIGN(16);
*(.vhex.xram)
} :NONE
. = ALIGN(16);
} > xram AT> userram
/*
** On-chip memory sections: X
*/
. = ORIGIN(xram);
.xram ALIGN(4) : ALIGN(4) {
*(.vhex.xram)
. = ALIGN(16);
} > xram
/* unwanted section */
/DISCARD/ : {
*(.rela.debug*)
*(.gnu.*)
*(.debug_info)
*(.debug_abbrev)
*(.debug_loc)
*(.debug_aranges)
*(.debug_ranges)
*(.debug_line)
*(.debug_str)
*(.debug_*)
*(.jcr)
*(.eh_frame_hdr)
*(.eh_frame)
*(.comment)
*(.interp)
}
/* unwanted section */
/DISCARD/ : {
*(.rela.debug*)
*(.gnu.*)
*(.debug_info)
*(.debug_abbrev)
*(.debug_loc)
*(.debug_aranges)
*(.debug_ranges)
*(.debug_line)
*(.debug_str)
*(.debug_*)
*(.jcr)
*(.eh_frame_hdr)
*(.eh_frame)
*(.comment)
*(.interp)
}
}

View File

@ -19,13 +19,13 @@
@x1 @y1 @x2 @y2 Endpoints of the line (both included).
@color Line color (same values as dpixel() are allowed) */
extern void dline(int x1, int y1, int x2, int y2, int color);
extern void dline(int color, int x1, int y1, int x2, int y2);
/* dhline() : render an horizontal line */
extern void dhline(int y, int x1, int x2, int color);
extern void dhline(int color, int y, int x1, int x2);
/* dvline() : render an vertical line */
extern void dvline(int x, int y1, int y2, int color);
extern void dvline(int color, int x, int y1, int y2);
//---
@ -33,13 +33,12 @@ extern void dvline(int x, int y1, int y2, int color);
//---
/* dline_render() : real drawing function */
extern void dline_render(dsurface_t *s, int x1, int y1, int x2, int y2, int c);
extern void dline_render(dsurface_t *s, int c, int x1, int y1, int x2, int y2);
/* dhline_render() : optimized drawing function for horizontal line */
extern void dhline_render(dsurface_t *s, int y, int x1, int x2, int color);
extern void dhline_render(dsurface_t *s, int color, int y, int x1, int x2);
/* dvline_render() : optimized drawing function for vertical line */
extern void dvline_render(dsurface_t *s, int x, int y1, int y2, int color);
extern void dvline_render(dsurface_t *s, int color, int x, int y1, int y2);
#endif /* __VHEX_DISPLAY_DRAW_LINE__ */

View File

@ -6,12 +6,14 @@
//---
/* drect_filled() : draw filled rectangle */
extern void drect_filled(int color, int x1, int y1, int x2, int y2);
extern void drect(int color, int x1, int y1, int x2, int y2);
//---
// Kernel-level API
//---
#include <vhex/display/types.h>
/* drect_filled() : draw filled rectangle */
extern void drect_filled_render(
dsurface_t *surface,

View File

@ -0,0 +1,432 @@
#ifndef __VHEX_MPU_SH7305_USB__
# define __VHEX_MPU_SH7305_USB__
#include <vhex/defs/attributes.h>
#include <vhex/defs/types.h>
struct __sh7305_usb
{
/* SYSCFG - System Configuration Control Register */
word_union(SYSCFG,
uint16_t const : 5;
uint16_t SCKE : 1; /* USB clock module controller */
uint16_t const : 1;
uint16_t const : 1;
uint16_t HSE : 1; /* High-speed operations enable */
uint16_t DCFM : 1; /* Function controller */
uint16_t DRPD : 1; /* D+/- Resistor Control */
uint16_t DPRPU : 1; /* D+ Resistor Control */
uint16_t const : 3;
uint16_t USBE : 1; /* USB operation enable */
);
/* BUSWAIT - CPU Bus Wait Setting Register */
word_union(BUSWAIT,
uint16_t const :12;
uint16_t BWAIT : 4; /* CPU Bus wait */
);
/* SYSSTS - System Configuration Status Register
* @notes
* - emulator allows writting LNST */
word_union(SYSSTS,
uint16_t const : 5;
uint16_t HIGH : 1; /* Should be 1 */
uint16_t const : 8;
uint16_t LNST : 2; /* USB Data Line Status */
);
pad(0x02);
/* DVTSTCCTR - Device State Controle Register */
word_union(DVSTCTR,
uint16_t const : 7;
uint16_t WKUP : 1; /* Wakeup Output */
uint16_t RWUPE : 1; /* Wakeup Detection Enable */
uint16_t USBRT : 1; /* USB Reset Output */
uint16_t RESUME : 1; /* Resume Output */
uint16_t UACT : 1; /* USB Bus Enable */
uint16_t const : 1;
uint16_t RHST : 3; /* Reset Handshake */
);
pad(0x02);
/* TESTMODE - Test Mode Register */
word_union(TESTMODE,
uint16_t const :12;
uint16_t UTST : 4; /* Test Mode */
);
pad(0x06);
/* [C/Dx]FIFO - FIFO Port Registers */
uint32_t CFIFO; /* DCP FIFO port */
uint32_t D0FIFO; /* Data 0 FIFO port */
uint32_t D1FIFO; /* Data 1 FIFO port */
/* CFIFOSEL - FIFO Port Select Register
* @notes
* - emulator register mask is 0xcd4f
* - physical (and SH7724) mask is 0xcd2f (ISEL shifted) */
word_union(CFIFOSEL,
uint16_t RCNT : 1; /* Read Count Mode */
uint16_t REW : 1; /* Pointer Buffer Rewind */
uint16_t const : 2;
uint16_t MBW : 2; /* Access Bits Width */
uint16_t const : 1;
uint16_t BIGEND : 1; /* Endiant Control */
uint16_t const : 2;
uint16_t ISEL : 1; /* Access Direction When DCP is used */
uint16_t const : 1;
uint16_t CURPIPE :4; /* Port Access Pipe Specification */
);
/* CFIFOCTR - FIFO Port Control Register */
word_union(CFIFOCTR,
uint16_t BVAL : 1; /* Buffer Memory Valid Flags */
uint16_t BCLR : 1; /* CPU Buffer Clear */
uint16_t FRDY : 1; /* FIFO Port Ready */
uint16_t const : 1;
uint16_t DTLN :12; /* Receive Data Length */
);
pad(0x04);
/* D0FIFOSEL - FIFO Port Select Register */
word_union(D0FIFOSEL,
uint16_t RCNT : 1; /* Read Count Mode */
uint16_t REW : 1; /* Pointer Buffer Rewind */
uint16_t DCLRM : 1; /* Auto Buffer Clear Mode */
uint16_t DREQE : 1; /* DMA Transfert Request Enable */
uint16_t MBW : 2; /* Access Bits Width */
uint16_t const : 1;
uint16_t BIGEND : 1; /* Endiant Control */
uint16_t const : 4;
uint16_t CURPIPE :4; /* Port Access Pipe Specification */
);
/* D0FIFOCTR - FIFO Port Control Register */
word_union(D0FIFOCTR,
uint16_t BVAL : 1; /* Buffer Memory Valid Flags */
uint16_t BCLR : 1; /* CPU Buffer Clear */
uint16_t FRDY : 1; /* FIFO Port Ready */
uint16_t const : 1;
uint16_t DTLN :12; /* Receive Data Length */
);
/* D1FIFOSEL - FIFO Port Select Register */
word_union(D1FIFOSEL,
uint16_t RCNT : 1; /* Read Count Mode */
uint16_t REW : 1; /* Pointer Buffer Rewind */
uint16_t DCLRM : 1; /* Auto Buffer Clear Mode */
uint16_t DREQE : 1; /* DMA Transfert Request Enable */
uint16_t MBW : 2; /* Access Bits Width */
uint16_t const : 1;
uint16_t BIGEND : 1; /* Endiant Control */
uint16_t const : 4;
uint16_t CURPIPE :4; /* Port Access Pipe Specification */
);
/* D1FIFOCTR - FIFO Port Control Register */
word_union(D1FIFOCTR,
uint16_t BVAL : 1; /* Buffer Memory Valid Flags */
uint16_t BCLR : 1; /* CPU Buffer Clear */
uint16_t FRDY : 1; /* FIFO Port Ready */
uint16_t const : 1;
uint16_t DTLN :12; /* Receive Data Length */
);
/* INTENB0 - Interrupt Enable Register */
word_union(INTENB0,
uint16_t VBSE : 1; /* VBUS */
uint16_t RSME : 1; /* Resume */
uint16_t SOFE : 1; /* Frame Number Update */
uint16_t DVSE : 1; /* Device State Transition */
uint16_t CTRE : 1; /* Control Transfert Stage Transition */
uint16_t BEMPE : 1; /* Buffer Empty */
uint16_t BRDYE : 1; /* Buffer Ready */
uint16_t const : 8;
);
pad(4);
/* BRDYENB - BRDY Interrupt Enable Register */
word_union(BRDYENB,
uint16_t const :6;
uint16_t PIPE9BRDYE :1; /* BRDY Interrupt enable for PIPE9 */
uint16_t PIPE8BRDYE :1; /* BRDY Interrupt enable for PIPE8 */
uint16_t PIPE7BRDYE :1; /* BRDY Interrupt enable for PIPE7 */
uint16_t PIPE6BRDYE :1; /* BRDY Interrupt enable for PIPE6 */
uint16_t PIPE5BRDYE :1; /* BRDY Interrupt enable for PIPE5 */
uint16_t PIPE4BRDYE :1; /* BRDY Interrupt enable for PIPE4 */
uint16_t PIPE3BRDYE :1; /* BRDY Interrupt enable for PIPE3 */
uint16_t PIPE2BRDYE :1; /* BRDY Interrupt enable for PIPE2 */
uint16_t PIPE1BRDYE :1; /* BRDY Interrupt enable for PIPE1 */
uint16_t PIPE0BRDYE :1; /* BRDY Interrupt enable for PIPE0 */
);
/* NRDYENB - NRDY Interrupt Enable Register */
word_union(NRDYENB,
uint16_t const :6;
uint16_t PIPE9NRDYE :1; /* NRDY Interrupt enable for PIPE9 */
uint16_t PIPE8NRDYE :1; /* NRDY Interrupt enable for PIPE8 */
uint16_t PIPE7NRDYE :1; /* NRDY Interrupt enable for PIPE7 */
uint16_t PIPE6NRDYE :1; /* NRDY Interrupt enable for PIPE6 */
uint16_t PIPE5NRDYE :1; /* NRDY Interrupt enable for PIPE5 */
uint16_t PIPE4NRDYE :1; /* NRDY Interrupt enable for PIPE4 */
uint16_t PIPE3NRDYE :1; /* NRDY Interrupt enable for PIPE3 */
uint16_t PIPE2NRDYE :1; /* NRDY Interrupt enable for PIPE2 */
uint16_t PIPE1NRDYE :1; /* NRDY Interrupt enable for PIPE1 */
uint16_t PIPE0NRDYE :1; /* NRDY Interrupt enable for PIPE0 */
);
/* BEMPENB - BEMP Interrupt Enable Register */
word_union(BEMPENB,
uint16_t const :6;
uint16_t PIPE9BEMPE :1; /* BEMP Interrupt enable for PIPE9 */
uint16_t PIPE8BEMPE :1; /* BEMP Interrupt enable for PIPE8 */
uint16_t PIPE7BEMPE :1; /* BEMP Interrupt enable for PIPE7 */
uint16_t PIPE6BEMPE :1; /* BEMP Interrupt enable for PIPE6 */
uint16_t PIPE5BEMPE :1; /* BEMP Interrupt enable for PIPE5 */
uint16_t PIPE4BEMPE :1; /* BEMP Interrupt enable for PIPE4 */
uint16_t PIPE3BEMPE :1; /* BEMP Interrupt enable for PIPE3 */
uint16_t PIPE2BEMPE :1; /* BEMP Interrupt enable for PIPE2 */
uint16_t PIPE1BEMPE :1; /* BEMP Interrupt enable for PIPE1 */
uint16_t PIPE0BEMPE :1; /* BEMP Interrupt enable for PIPE0 */
);
/* SOFCFG - SOF Control Register */
word_union(SOFCFG,
uint16_t :7;
uint16_t TRNENSEL :1; /* Transaction-Enabled Time Select */
uint16_t :1;
uint16_t BRDYM :1; /* BRDY Status Clear Timing */
uint16_t HIGH :1; /* SHOULD BE SET TO 1 MANUALLY */
uint16_t :5;
);
pad(2);
/* Interrupt Status Registers */
word_union(INTSTS0,
uint16_t VBINT : 1; /* VBUS */
uint16_t RESM : 1; /* Resume */
uint16_t SOFR : 1; /* Frame Number Refresh */
uint16_t DVST : 1; /* Device State Transition */
uint16_t CTRT : 1; /* Control Transfer Stage Transition */
uint16_t BEMP : 1; /* Buffer Empty */
uint16_t NRDY : 1; /* Buffer Not Ready */
uint16_t BRDY : 1; /* Buffer Ready */
uint16_t VBSTS : 1; /* VBUS Input Status */
uint16_t DVSQ : 3; /* Device state */
uint16_t VALID : 1; /* USB Request Reception */
uint16_t CTSQ : 3; /* Control Transfer Stage */
);
pad(4);
/* BRDYENB - BRDY Interrupt Status Register */
word_union(BRDYSTS,
uint16_t const :6;
uint16_t PIPE9BRDY :1; /* BRDY Interrupt Status for PIPE9 */
uint16_t PIPE8BRDY :1; /* BRDY Interrupt Status for PIPE8 */
uint16_t PIPE7BRDY :1; /* BRDY Interrupt Status for PIPE7 */
uint16_t PIPE6BRDY :1; /* BRDY Interrupt Status for PIPE6 */
uint16_t PIPE5BRDY :1; /* BRDY Interrupt Status for PIPE5 */
uint16_t PIPE4BRDY :1; /* BRDY Interrupt Status for PIPE4 */
uint16_t PIPE3BRDY :1; /* BRDY Interrupt Status for PIPE3 */
uint16_t PIPE2BRDY :1; /* BRDY Interrupt Status for PIPE2 */
uint16_t PIPE1BRDY :1; /* BRDY Interrupt Status for PIPE1 */
uint16_t PIPE0BRDY :1; /* BRDY Interrupt Status for PIPE0 */
);
/* NRDYENB - NRDY Interrupt Status Register */
word_union(NRDYSTS,
uint16_t const :6;
uint16_t PIPE9NRDY :1; /* NRDY Interrupt Status for PIPE9 */
uint16_t PIPE8NRDY :1; /* NRDY Interrupt Status for PIPE8 */
uint16_t PIPE7NRDY :1; /* NRDY Interrupt Status for PIPE7 */
uint16_t PIPE6NRDY :1; /* NRDY Interrupt Status for PIPE6 */
uint16_t PIPE5NRDY :1; /* NRDY Interrupt Status for PIPE5 */
uint16_t PIPE4NRDY :1; /* NRDY Interrupt Status for PIPE4 */
uint16_t PIPE3NRDY :1; /* NRDY Interrupt Status for PIPE3 */
uint16_t PIPE2NRDY :1; /* NRDY Interrupt Status for PIPE2 */
uint16_t PIPE1NRDY :1; /* NRDY Interrupt Status for PIPE1 */
uint16_t PIPE0NRDY :1; /* NRDY Interrupt Status for PIPE0 */
);
/* BEMPENB - BEMP Interrupt Status Register */
word_union(BEMPSTS,
uint16_t const :6;
uint16_t PIPE9BEMP :1; /* BEMP Interrupt Status for PIPE9 */
uint16_t PIPE8BEMP :1; /* BEMP Interrupt Status for PIPE8 */
uint16_t PIPE7BEMP :1; /* BEMP Interrupt Status for PIPE7 */
uint16_t PIPE6BEMP :1; /* BEMP Interrupt Status for PIPE6 */
uint16_t PIPE5BEMP :1; /* BEMP Interrupt Status for PIPE5 */
uint16_t PIPE4BEMP :1; /* BEMP Interrupt Status for PIPE4 */
uint16_t PIPE3BEMP :1; /* BEMP Interrupt Status for PIPE3 */
uint16_t PIPE2BEMP :1; /* BEMP Interrupt Status for PIPE2 */
uint16_t PIPE1BEMP :1; /* BEMP Interrupt Status for PIPE1 */
uint16_t PIPE0BEMP :1; /* BEMP Interrupt Status for PIPE0 */
);
/* FRMNUM - Frame Number Register */
word_union(FRMNUM,
uint16_t OVRN : 1; /* Overrun/Underrun Detection Status */
uint16_t CRCE : 1; /* Receive Data Error */
uint16_t : 3;
uint16_t FRNM :11; /* Frame Number */
);
/* UFRMNUM - uFrame Number Register */
word_union(UFRMNUM,
uint16_t :13;
uint16_t UFRNM : 3; /* uFrame */
);
/* USBADDR - USB Address Register
* @notes
* - emulator allow writting to this register but is probably only for
* register initialization */
word_union(USBADDR,
uint16_t : 9;
uint16_t USBADDR : 7; /* USB Address */
);
pad(2);
/* USBREQ - USB Request Type Register */
word_union(USBREQ,
uint16_t BREQUEST :8; /* USB request data value */
uint16_t BMREQUEST :8; /* USB request type value */
);
/* USBVAL - USB Request Value Register */
word_union(USBVAL,
uint16_t WVALUE :16; /* USB request wValue value */
);
/* USBINDX - USB Request Index Register */
word_union(USBINDX,
uint16_t WINDEX :16; /* USB USB request wIndex value */
);
/* USBLENG - USB Request Length Register */
word_union(USBLENG,
uint16_t WLENGTH :16; /* USB USB request wLength value */
);
/* DCPCFG - DCP Configuration Register */
word_union(DCPCFG,
uint16_t :11;
uint16_t DIR : 1; /* Transfer Direction */
uint16_t : 4;
);
/* DCPMAXP - DCP Maximum Packet Size Register */
word_union(DCPMAXP,
uint16_t DEVSEL : 4; /* Device Select */
uint16_t : 5;
uint16_t MXPS : 7; /* Maximum Packet Size */
);
/* DCPCTR - DCP Control Register */
word_union(DCPCTR,
uint16_t BSTS : 1; /* Buffer Status */
uint16_t SUREQ : 1; /* SETUP Token Transmission */
uint16_t CSCLR : 1; /* C-SPLIT Status Clear */
uint16_t CSSTS : 1; /* C-SPLIT Status */
uint16_t SUREQCLR : 1; /* SUREQ Bit Clear */
uint16_t : 2;
uint16_t SQCLR : 1; /* Toggle Bit Clear */
uint16_t SQSET : 1; /* Toggle Bit Set */
uint16_t SQMON : 1; /* Sequence Toggle Bit Monitor */
uint16_t PBUSY : 1; /* Pipe Busy */
uint16_t PINGE : 1; /* PING Token Issue Enable */
uint16_t : 1;
uint16_t CCPL : 1; /* Control Transfer End Enable */
uint16_t PID : 2; /* Response PID */
);
pad(2);
/* PIPESEL - Pipe Window Select Register */
word_union(PIPESEL,
uint16_t :12;
uint16_t PIPESEL : 4; /* Pipe Window Select */
);
pad(2);
/* PIPECFG - Pipe Configuration Register */
word_union(PIPECFG,
uint16_t TYPE : 2; /* Transfer Type */
uint16_t : 3;
uint16_t BFRE : 1; /* BRDY Interrupt Operation Specification */
uint16_t DBLB : 1; /* Double Buffer Mode */
uint16_t CNTMD : 1; /* Continuous Transfer Mode */
uint16_t SHTNAK : 1; /* Pipe Disabled at End of Transfer */
uint16_t : 2;
uint16_t DIR : 1; /* Transfer Direction */
uint16_t EPNUM : 4; /* Endpoint Number */
);
/* PIPEBUF - Pipe Buffer Setting Register */
word_union(PIPEBUF,
uint16_t : 1;
uint16_t BUFSIZE : 5; /* Buffer Size */
uint16_t : 2;
uint16_t BUFNMB : 8; /* Buffer Number */
);
/* PIPEMAXP - Pipe Maximum Packet Size Register */
word_union(PIPEMAXP,
uint16_t DEVSEL : 4; /* Device Select */
uint16_t : 1;
uint16_t MXPS :11; /* Maximum Packet Size */
);
/* PIPEPERI - Pipe Timing Control Register */
word_union(PIPEPERI,
uint16_t : 3;
uint16_t IFIS : 1; /* Isochronous IN Buffer Flush */
uint16_t : 9;
uint16_t IITV : 3; /* Interval Error Detection Interval */
);
/* PIPECTR - PIPEn Control Registers
* @notes
* - PIPECTR1 mask = 0xf7e3
* - PIPECTR2 mask = 0xf7e3
* - PIPECTR3 mask = 0xf7e3
* - PIPECTR4 mask = 0xf7e3
* - PIPECTR5 mask = 0xf7e3
* - PIPECTR6 mask = 0xb3e3
* - PIPECTR7 mask = 0xb3e3
* - PIPECTR8 mask = 0xb3e3
* - PIPECTR9 mask = 0xb3e3 */
word_union(PIPECTR[9],
uint16_t BSTS : 1; /* Buffer Status */
uint16_t INBUFM : 1; /* IN Buffer Monitor (PIPE1..5) */
uint16_t CSCLR : 1; /* C-SPLIT Status Clear Bit */
uint16_t CSSTS : 1; /* CSSTS Status Bit */
uint16_t : 1;
uint16_t ATREPM : 1; /* Auto Response Mode (PIPE1..5) */
uint16_t ACLRM : 1; /* Auto Buffer Clear Mode */
uint16_t SQCLR : 1; /* Toggle Bit Clear */
uint16_t SQSET : 1; /* Toggle Bit Set */
uint16_t SQMON : 1; /* Toggle Bit Confirmation */
uint16_t PBUSY : 1; /* Pipe Busy */
uint16_t : 3;
uint16_t PID : 2; /* Response PID */
);
pad(14);
/* PIPEnTRE - PIPEn Transaction Counter Enable Registers and */
/* PIPEnTRN - PIPEn Transaction Counter Registers */
struct {
word_union(PIPEnTRE,
uint16_t : 6;
uint16_t TRENB : 1; /* Transaction Counter Enable */
uint16_t TRCLR : 1; /* Transaction Counter Clear */
uint16_t : 8;
);
word_union(PIPEnTRN,
uint16_t TRCNT :16; /* Transaction Counter */
);
} PIPETR[5];
};
/* UPONCR - USB Power Control Register */
union __sh7305_usb_uponcr
{
uint16_t WORD;
struct {
uint16_t const : 5;
uint16_t UPON : 2; /* USB Power Control */
uint16_t const : 9;
} __attribute__((packed, aligned(2)));
} __attribute__((packed, aligned(2)));
#define SH7305_USB (*(volatile struct __sh7305_usb *)0xa4d80000)
#define SH7305_UPONCR (*(volatile union __sh7305_usb_uponcr *)0xa40501d4)
#endif /*__VHEX_MPU_SH7305_USB__ */

View File

@ -7,78 +7,125 @@
// fake interrupt handler
//---
#define __SDL2_KEYCODE_SUPPORTED 16
static struct {
int sdl2_id;
char const * const sdl2_name;
int vhex_id;
char const * const vhex_name;
} key_translation[__SDL2_KEYCODE_SUPPORTED] = {
} key_translation[] = {
/* F-keys */
{
.sdl2_id = 49, .sdl2_name = "1",
.vhex_id = VKEY_F1, .vhex_name = "F1"
.sdl2_id = SDLK_F1, .sdl2_name = "F1",
.vhex_id = VKEY_F1, .vhex_name = "F1"
},
{
.sdl2_id = 50, .sdl2_name = "2",
.vhex_id = VKEY_F2, .vhex_name = "F2"
.sdl2_id = SDLK_F2, .sdl2_name = "F2",
.vhex_id = VKEY_F2, .vhex_name = "F2"
},
{
.sdl2_id = 51, .sdl2_name = "3",
.vhex_id = VKEY_F3, .vhex_name = "F3"
.sdl2_id = SDLK_F3, .sdl2_name = "F3",
.vhex_id = VKEY_F3, .vhex_name = "F3"
},
{
.sdl2_id = 52, .sdl2_name = "4",
.vhex_id = VKEY_F4, .vhex_name = "F4"
.sdl2_id = SDLK_F4, .sdl2_name = "F4",
.vhex_id = VKEY_F4, .vhex_name = "F4"
},
{
.sdl2_id = 53, .sdl2_name = "5",
.vhex_id = VKEY_F5, .vhex_name = "F5"
.sdl2_id = SDLK_F5, .sdl2_name = "F5",
.vhex_id = VKEY_F5, .vhex_name = "F5"
},
{
.sdl2_id = 54, .sdl2_name = "6",
.vhex_id = VKEY_F6, .vhex_name = "F6"
.sdl2_id = SDLK_F6, .sdl2_name = "F6",
.vhex_id = VKEY_F6, .vhex_name = "F6"
},
/* Numeric keys */
{
.sdl2_id = SDLK_1, .sdl2_name = "1",
.vhex_id = VKEY_1, .vhex_name = "1"
},
{
.sdl2_id = 0x4000004f, .sdl2_name = "right arrow",
.vhex_id = VKEY_RIGHT, .vhex_name = "right arrow"
.sdl2_id = SDLK_2, .sdl2_name = "2",
.vhex_id = VKEY_2, .vhex_name = "2"
},
{
.sdl2_id = 0x40000050, .sdl2_name = "left arrow",
.vhex_id = VKEY_LEFT, .vhex_name = "left arrow"
.sdl2_id = SDLK_3, .sdl2_name = "3",
.vhex_id = VKEY_3, .vhex_name = "3"
},
{
.sdl2_id = 0x40000051, .sdl2_name = "down arrow",
.vhex_id = VKEY_DOWN, .vhex_name = "down arrow"
.sdl2_id = SDLK_4, .sdl2_name = "4",
.vhex_id = VKEY_4, .vhex_name = "4"
},
{
.sdl2_id = 0x40000052, .sdl2_name = "up arrow",
.vhex_id = VKEY_UP, .vhex_name = "up arrow"
.sdl2_id = SDLK_5, .sdl2_name = "5",
.vhex_id = VKEY_5, .vhex_name = "5"
},
{
.sdl2_id = 13, .sdl2_name = "enter",
.vhex_id = VKEY_EXE, .vhex_name = "EXE"
.sdl2_id = SDLK_6, .sdl2_name = "6",
.vhex_id = VKEY_6, .vhex_name = "6"
},
{
.sdl2_id = 0x400000e0, .sdl2_name = "shift",
.vhex_id = VKEY_ALPHA, .vhex_name = "ALPHA"
.sdl2_id = SDLK_7, .sdl2_name = "7",
.vhex_id = VKEY_7, .vhex_name = "7"
},
{
.sdl2_id = 0x400000e1, .sdl2_name = "ctrl",
.vhex_id = VKEY_SHIFT, .vhex_name = "SHIFT"
.sdl2_id = SDLK_8, .sdl2_name = "8",
.vhex_id = VKEY_8, .vhex_name = "8"
},
{
.sdl2_id = 27, .sdl2_name = "echap",
.vhex_id = VKEY_EXIT, .vhex_name = "EXIT"
.sdl2_id = SDLK_9, .sdl2_name = "9",
.vhex_id = VKEY_9, .vhex_name = "9"
},
/* Arrows */
{
.sdl2_id = SDLK_RIGHT, .sdl2_name = "right arrow",
.vhex_id = VKEY_RIGHT, .vhex_name = "right arrow"
},
{
.sdl2_id = 8, .sdl2_name = "backspace",
.vhex_id = VKEY_DEL, .vhex_name = "DEL"
.sdl2_id = SDLK_LEFT, .sdl2_name = "left arrow",
.vhex_id = VKEY_LEFT, .vhex_name = "left arrow"
},
{
.sdl2_id = 9, .sdl2_name = "tab",
.vhex_id = VKEY_MENU, .vhex_name = "MENU"
.sdl2_id = SDLK_DOWN, .sdl2_name = "down arrow",
.vhex_id = VKEY_DOWN, .vhex_name = "down arrow"
},
{
.sdl2_id = SDLK_UP, .sdl2_name = "up arrow",
.vhex_id = VKEY_UP, .vhex_name = "up arrow"
},
/* special keys */
{
.sdl2_id = SDLK_KP_ENTER, .sdl2_name = "enter",
.vhex_id = VKEY_EXE, .vhex_name = "EXE"
},
{
.sdl2_id = SDLK_LSHIFT, .sdl2_name = "left shift",
.vhex_id = VKEY_ALPHA, .vhex_name = "ALPHA"
},
{
.sdl2_id = SDLK_RSHIFT, .sdl2_name = "right shift",
.vhex_id = VKEY_SHIFT, .vhex_name = "SHIFT"
},
{
.sdl2_id = SDLK_ESCAPE, .sdl2_name = "echap",
.vhex_id = VKEY_EXIT, .vhex_name = "EXIT"
},
{
.sdl2_id = SDLK_BACKSPACE, .sdl2_name = "backspace",
.vhex_id = VKEY_DEL, .vhex_name = "DEL"
},
{
.sdl2_id = SDLK_TAB, .sdl2_name = "tab",
.vhex_id = VKEY_MENU, .vhex_name = "MENU"
},
/* end of translation table */
{
.sdl2_id = -1, .sdl2_name = NULL,
.vhex_id = -1, .vhex_name = NULL
}
};
@ -109,7 +156,7 @@ static int sdl_keycache_event_pop(vkey_event_t *event)
if (evt.type != SDL_KEYDOWN && evt.type != SDL_KEYUP)
continue;
for (int i = 0; i < __SDL2_KEYCODE_SUPPORTED ; ++i) {
for (int i = 0; key_translation[i].sdl2_name != NULL; ++i) {
if (evt.key.keysym.sym != key_translation[i].sdl2_id)
continue;
@ -137,7 +184,7 @@ static void __keysc_configure(void)
printf(" +-------------+-------------+\n");
printf(" | OS | Vhex |\n");
printf(" +-------------+-------------+\n");
for (int i = 0; i < __SDL2_KEYCODE_SUPPORTED; ++i) {
for (int i = 0; key_translation[i].sdl2_name != NULL; ++i) {
printf(
" | %-11s | %-11s |\n",
key_translation[i].sdl2_name,

View File

@ -12,7 +12,7 @@
Relies on platform-dependent dhline() and dvline() for optimized situations.
@x1 @y1 @x2 @y2 Coordinates of endpoints of line (included)
@color Any color accepted by dpixel() on the platform */
void dline_render(dsurface_t *s, int x1, int y1, int x2, int y2, int color)
void dline_render(dsurface_t *s, int color, int x1, int y1, int x2, int y2)
{
int i;
int x = x1;
@ -60,7 +60,7 @@ void dline_render(dsurface_t *s, int x1, int y1, int x2, int y2, int color)
}
/* dhline_render() : optimized horizontal line */
void dhline_render(dsurface_t *surface, int y, int x1, int x2, int color)
void dhline_render(dsurface_t *surface, int color, int y, int x1, int x2)
{
/* Order and bounds */
if(y < surface->y1 || y > surface->y2) return;
@ -105,7 +105,7 @@ void dhline_render(dsurface_t *surface, int y, int x1, int x2, int color)
}
/* dvline_render() : optimized drawing function for vertical line */
void dvline_render(dsurface_t *surface, int x, int y1, int y2, int color)
void dvline_render(dsurface_t *surface, int color, int x, int y1, int y2)
{
/* Order and bounds */
if(x < surface->x1 || x > surface->x2) return;
@ -180,7 +180,7 @@ void dvline_dstack(dsurface_t *surface, uintptr_t *args)
//---
/* dline(): Render a straight line */
void dline(int x1, int y1, int x2, int y2, int color)
void dline(int color, int x1, int y1, int x2, int y2)
{
if(color == C_NONE) return;
@ -188,7 +188,7 @@ void dline(int x1, int y1, int x2, int y2, int color)
if(y1 == y2)
{
dstack_add_action(
DSTACK_CALL(&dhline_dstack, y1, x1, x2, color),
DSTACK_CALL(&dhline_dstack, color, y1, x1, x2),
NULL,
NULL
);
@ -197,34 +197,34 @@ void dline(int x1, int y1, int x2, int y2, int color)
if(x1 == x2)
{
dstack_add_action(
DSTACK_CALL(&dvline_dstack, x1, y1, y2, color),
DSTACK_CALL(&dvline_dstack, color, x1, y1, y2),
NULL,
NULL
);
return;
}
dstack_add_action(
DSTACK_CALL(&dline_dstack, x1, y1, x2, y2, color),
DSTACK_CALL(&dline_dstack, color, x1, y1, x2, y2),
NULL,
NULL
);
}
/* dhline() : render an horizontal line */
void dhline(int y, int x1, int x2, int color)
void dhline(int color, int y, int x1, int x2)
{
dstack_add_action(
DSTACK_CALL(&dhline_dstack, y, x1, x2, color),
DSTACK_CALL(&dhline_dstack, color, y, x1, x2),
NULL,
NULL
);
}
/* dvline() : render an vertical line */
void dvline(int x, int y1, int y2, int color)
void dvline(int color, int x, int y1, int y2)
{
dstack_add_action(
DSTACK_CALL(&dvline_dstack, x, y1, y2, color),
DSTACK_CALL(&dvline_dstack, color, x, y1, y2),
NULL,
NULL
);

View File

@ -14,7 +14,7 @@ void drect_filled_render(
if (y1 > y2) swap(y1, y2);
for (int y = y1 ; y <= y2 ; ++y) {
dhline_render(surface, y, x1, x2, color);
dhline_render(surface, color, y, x1, x2);
}
}
@ -40,7 +40,7 @@ static void drect_filled_dstack(dsurface_t *surface, uintptr_t *args)
//---
/* plasma() : draw plasma effect */
void drect_filled(int color, int x1, int y1, int x2, int y2)
void drect(int color, int x1, int y1, int x2, int y2)
{
dstack_add_action(
DSTACK_CALL(&drect_filled_dstack, color, x1, y1, x2, y2),

View File

@ -1,6 +1,6 @@
[project]
name = 'vxkernel'
version = 0.7.0
version = '0.7.0'
type = 'lib'
target = [
'fxcg50',