gint: switch away from FX9860G/FXCG50 macros

Not changing much for now, just distilling them into hardware/OS/render
macros. Later on the rendering stuff will become more dynamic and down
the line I want to unify the APIs more.
This commit is contained in:
Lephe 2024-03-23 23:57:23 +01:00
parent ee109e4977
commit 3a42b5d386
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
20 changed files with 122 additions and 96 deletions

31
TODO
View File

@ -3,7 +3,7 @@ Bugs to fix:
Extensions on existing code:
* clock: mono support
* usb: add PC->calc reading, and interrupt pipes
* usb: and interrupt pipes
* fs: support RAM files
* fs: support USB streams as generic file descriptors
* fugue: support glob() to abstract away BFile entirely
@ -24,3 +24,32 @@ Future directions:
* Serial communication
* Make fx9860g projects work out of the box on fxcg50
* Base for Yatis' threads library
TODO:
* SPLIT CONFIG HEADER IN VARIANTS SO THEY DON'T CLASH WHEN INSTALLED
Bits that need to abstract out into APIs:
- display: Toggle backlight (or set level)
-> Have a backlight property with min/max values
@ getkey
@ justui jscene
- os: OS interface to access OS info, like in fxos
@ usb/setup.c set_strings
@ usb/classes/ff-bulk.c identify command
- render: current video mode
@ usb/classes/ff-bulk.c capture_vram
- gray: make gray engine a subset of t6k11 which then supports two modes
Video formats:
- i1msb
- 2i1msb
- rgb565
T6K11:
mode 0 : i1msb 128x64 @64 Hz
mode 1 : 2i1msb 128x64 @64 Hz
R61524:
mode 0 : rgb565 396x224 @? Hz
mode 1 : i3??? 396x224 @? Hz
mode 2 : i1msb 128x64 @? Hz # <- for g1a emulation :)
mode 3 : 2i1msb 128x64 @? Hz # <- for g1a emulation :)

View File

@ -161,6 +161,11 @@ SECTIONS
_silram = SIZEOF(.ilram);
_sxyram = SIZEOF(.xyram);
_lgmapped = ABSOLUTE(0);
_sgmapped = ABSOLUTE(0);
_lreloc = ABSOLUTE(0);
_sreloc = ABSOLUTE(0);
/* gint's uninitialized BSS section, going to static RAM. All the large
data arrays will be located here */
.gint.bss (NOLOAD) : {

View File

@ -18,9 +18,11 @@
#if defined(FX9860G)
# define GINT_HW_FX 1
# define GINT_HW_CG 0
# define GINT_HW_SWITCH(FX,CG) (FX)
#elif defined(FXCG50)
# define GINT_HW_FX 0
# define GINT_HW_CG 1
# define GINT_HW_SWITCH(FX,CG) (CG)
#endif
/* Shorthand to simplify definitions below. Won't be needed for long. */
@ -34,6 +36,7 @@
see no reason this would be different from hardware, but who knows. */
#define GINT_OS_FX GINT_HW_FX
#define GINT_OS_CG GINT_HW_CG
#define GINT_OS_SWITCH GINT_HW_SWITCH
/* GINT_NO_OS_STACK: Disables using a chunk of the OS stack as a heap. The top
section covering 355/512 ko is otherwise used. (fx-CG 50) */

View File

@ -18,6 +18,8 @@
extern "C" {
#endif
#include <gint/config.h>
/* For compatibility with ASM, include the following bits only in C code */
#ifndef CPP_ASM
@ -40,20 +42,14 @@ void hw_detect(void);
dual-platform version for libraries.
Warning: this macro is also used hardcoded in exch.s. */
#if defined(FX9860G) || (!defined(FX9860G) && !defined(FXCG50))
#define isSH3() (gint[HWMPU] & 1)
#define isSH4() (!isSH3())
#endif
#if defined(FX9860G)
#define isSlim() (gint[HWCALC] == HWCALC_FX9860G_SLIM)
#else
#define isSlim() 0
#endif
#ifdef FXCG50
#define isSH3() 0
#define isSH4() 1
#if GINT_HW_FX
# define isSH3() (gint[HWMPU] & 1)
# define isSH4() (!isSH3())
# define isSlim() (gint[HWCALC] == HWCALC_FX9860G_SLIM)
#elif GINT_HW_CG
# define isSH3() 0
# define isSH4() 1
# define isSlim() 0
#endif
/* This bit should be set in all data longwords except HWMPU, HWCPUVR, HWCPUPR

View File

@ -253,8 +253,7 @@ enum {
GETKEY_REP_PROFILE = 0x0040,
/* Enable application shortcuts; see getkey_set_feature_function() */
GETKEY_FEATURES = 0x0080,
/* After coming back from the main menu, redraw the screen with dupdate
(has an effect on fx-CG 50 only) */
/* After coming back from the main menu, redraw the screen with dupdate */
GETKEY_MENU_DUPDATE = 0x0100,
/* After coming back from the main menu, send a KEYEV_OSMENU event */
GETKEY_MENU_EVENT = 0x0200,

View File

@ -32,6 +32,7 @@ extern "C" {
#endif
#include <gint/usb.h>
#include <gint/config.h>
struct usb_fxlink_header;
/* This bulk transfer interface with class code 0xff/0x77 implements a simple
@ -74,7 +75,7 @@ void usb_fxlink_screenshot(bool onscreen);
automatically send new frames to fxlink. */
void usb_fxlink_videocapture(bool onscreen);
#ifdef FX9860G
#if GINT_RENDER_MONO
/* Similar to usb_fxlink_screenshot(), but takes a gray screenshot if the gray
engine is currently running. */
void usb_fxlink_screenshot_gray(bool onscreen);

View File

@ -5,6 +5,7 @@
#include <gint/drivers.h>
#include <gint/drivers/states.h>
#include <gint/clock.h>
#include <gint/config.h>
#include <gint/hardware.h>
#include <gint/mpu/cpg.h>
@ -26,7 +27,7 @@ const clock_frequency_t *clock_freq(void)
// SH7705 Clock signals
//---
#if defined(FX9860G) || (!defined(FX9860G) && !defined(FXCG50))
#if GINT_HW_FX
void sh7705_probe(void)
{
@ -57,7 +58,7 @@ void sh7705_probe(void)
freq.Pphi_f = (ckio * pll1) / freq.Pphi_div;
}
#endif /* FX9860G and platform-agnostic */
#endif
//---
// SH7305 clock signals
@ -111,7 +112,7 @@ void cpg_compute_freq(void)
{
/* This avoids warnings about sh7705_probe() being undefined when
building for fxcg50 */
#if defined(FX9860G) || (!defined(FX9860G) && !defined(FXCG50))
#if GINT_HW_FX
isSH3() ? sh7705_probe() :
#endif
sh7305_probe();

View File

@ -141,7 +141,7 @@ void cpg_set_overclock_setting(struct cpg_overclock_setting const *s)
cpu_atomic_end();
}
#ifdef FX9860G
#if GINT_HW_FX
static struct cpg_overclock_setting const settings_fx9860g_sh3[5] = {
/* CLOCK_SPEED_F1 */
@ -312,9 +312,9 @@ static struct cpg_overclock_setting const settings_g35pe2[5] = {
.CS5aWCR = 0x00031B40 },
};
#endif /* FX9860G */
#endif
#ifdef FXCG50
#if GINT_HW_CG
static struct cpg_overclock_setting const settings_prizm[5] = {
/* CLOCK_SPEED_F1 */
@ -432,25 +432,25 @@ static struct cpg_overclock_setting const settings_fxcg50[5] = {
.CS5aWCR = 0x000203C1 },
};
#endif /* FXCG50 */
#endif
static struct cpg_overclock_setting const *get_settings(void)
{
#ifdef FX9860G
#if GINT_HW_FX
if(gint[HWCALC] == HWCALC_FX9860G_SH3)
return settings_fx9860g_sh3;
if(gint[HWCALC] == HWCALC_FX9860G_SH4)
return settings_fx9860g_sh4;
if(gint[HWCALC] == HWCALC_G35PE2)
return settings_g35pe2;
#endif /* FX9860G */
#endif
#ifdef FXCG50
#if GINT_HW_CG
if(gint[HWCALC] == HWCALC_PRIZM)
return settings_prizm;
if(gint[HWCALC] == HWCALC_FXCG50)
return settings_fxcg50;
#endif /* FXCG50 */
#endif
return NULL;
}

View File

@ -6,6 +6,7 @@
#include <gint/defs/attributes.h>
#include <gint/hardware.h>
#include <gint/gint.h>
#include <gint/config.h>
#include <stdlib.h>
#include <string.h>
@ -59,7 +60,7 @@ GNORETURN static void gint_default_panic(GUNUSED uint32_t code)
dfont(NULL);
#ifdef FX9860G
#if GINT_RENDER_MONO
memset(gint_vram, 0, 1024);
dtext(1, 0, "Exception! (SysERROR)");
for(int i = 0; i < 32; i++) gint_vram[i] = ~gint_vram[i];
@ -96,7 +97,7 @@ GNORETURN static void gint_default_panic(GUNUSED uint32_t code)
}
#endif
#ifdef FXCG50
#if GINT_RENDER_RGB
/* Don't require the DMA driver just for a clear */
memset(gint_vram, 0xff, DWIDTH*DHEIGHT*2);
dtext(6, 3, "An exception occured! (System ERROR)");

View File

@ -8,6 +8,7 @@
#include <gint/defs/types.h>
#include <gint/defs/util.h>
#include <gint/mpu/pfc.h>
#include <gint/config.h>
#include <string.h>
@ -19,7 +20,7 @@ GBSS uint32_t gint[HW_KEYS];
/* Product Register */
#define PRR (*((volatile uint32_t *)0xff000044))
#if defined(FX9860G) || (!defined(FX9860G) && !defined(FXCG50))
#if GINT_HW_FX
/* mpu_detect() - detect the underlying MPU
Many thanks to Simon Lothar for relevant documentation.
@ -116,9 +117,7 @@ void hw_detect(void)
else utlb_mapped_memory(NULL, NULL);
}
#endif /* FX9860G and platform-agnostic */
#ifdef FXCG50
#elif GINT_HW_CG
/* hw_detect(): Basic hardware detection */
void hw_detect(void)
@ -146,4 +145,6 @@ void hw_detect(void)
utlb_mapped_memory(NULL, NULL);
}
#endif /* FXCG50 */
#else
#error unknown hardware type for hw_detect
#endif

View File

@ -7,10 +7,11 @@
#define CPP_ASM
#include <gint/hardware.h>
#include <gint/config.h>
.global _gint_inth_7305
#ifdef FX9860G
#if GINT_HW_FX
.global _gint_inth_7705
#endif
@ -100,7 +101,7 @@ _gint_inth_7305:
1: .long 0xff000028
.first_entry:
#ifdef FX9860G
#if GINT_HW_FX
/* SH7705-TYPE INTERRUPT HANDLER ENTRY - 56 BYTES */

View File

@ -42,7 +42,7 @@ void kinit(void)
{
uint32_t VBR = 0;
#ifdef FX9860G
#if GINT_HW_FX
/* On fx-9860G, VBR is loaded at the end of the user RAM. On SH4, the
end of the user RAM hosts the stack, for which we leave 12 kB
(0x3000 bytes). The VBR space takes about 0x600 bytes on SH3 due to
@ -60,9 +60,9 @@ void kinit(void)
/* VBR is advanced 0x100 bytes because of an unused gap */
uram_end -= (isSH3() ? 0x600 : 0x1100);
VBR = uram_end - 0x100;
#endif /* FX9860G */
#endif
#ifdef FXCG50
#if GINT_HW_CG
/* On fx-CG 50, VBR is loaded at the start of the user RAM; the linker
script leaves 5 kB (0x1400 bytes) before the start of the data
segment. The stack is again placed at the end of the region, and we
@ -96,7 +96,7 @@ void kinit(void)
kmalloc_add_arena(&static_ram);
/* Create an arena in the OS stack as well, for VRAM and more data */
#if defined(FXCG50) && !defined(GINT_NO_OS_STACK)
#if GINT_HW_CG && !defined(GINT_NO_OS_STACK)
static kmalloc_arena_t os_stack = { 0 };
os_stack.name = "_ostk";
os_stack.is_default = true;
@ -107,13 +107,14 @@ void kinit(void)
os_stack.end = os_stack.start + (350 * 1024);
kmalloc_init_arena(&os_stack, true);
kmalloc_add_arena(&os_stack);
#endif /* FXCG50 && !GINT_NO_OS_STACK */
#endif
/* Allocate world buffers for the OS and for gint */
gint_world_os = gint_world_alloc();
gint_world_addin = gint_world_alloc();
gint_driver_flags = malloc(gint_driver_count());
/* Allocate VRAMs, which is important for panic screens */
extern bool dvram_init(void);
if(!dvram_init())
abort();

View File

@ -29,7 +29,7 @@ static void __osmenu_handler(void)
__Timer_Deinstall(__osmenu_id);
}
#ifdef FXCG50
#if GINT_OS_CG
typedef void (os_menu_function_t)(void);
/* This method is possible thanks to reverse-engineering by Dr-Carlos.
@ -97,7 +97,7 @@ void gint_osmenu_native(void)
__ClearKeyBuffer();
gint_copy_vram();
#ifdef FXCG50
#if GINT_OS_CG
/* Unfortunately ineffective (main menu probably reenables it)
__ConfigureStatusArea(3); */

View File

@ -25,12 +25,9 @@ extern uint32_t
ldata, sdata, rdata, /* User's data section */
lilram, silram, rilram, /* IL memory section */
lxyram, sxyram, rxyram, /* X and Y memory section */
sbss, rbss; /* User's BSS section */
#ifdef FX9860G
extern uint32_t
sbss, rbss, /* User's BSS section */
lgmapped, sgmapped, /* Permanently mapped functions */
lreloc, sreloc; /* Relocatable references */
#endif
/* Constructor and destructor arrays */
extern void (*bctors)(void), (*ectors)(void);
@ -136,7 +133,7 @@ static int start2(int isappli, int optnum)
1.00 and the fx-9860G emulator) is not clear yet, so gint can't load
pages dynamically. Load everything preventively (works only if the
add-in is small enough) */
#ifdef FX9860G
#if GINT_OS_FX
if(isSH3())
{
/* Try to map every ROM address up to _srom */
@ -159,9 +156,8 @@ static int start2(int isappli, int optnum)
gint_load_onchip_sections();
#ifdef FX9860G
/* Copy permanently-mapped code to start of user RAM (on fx-CG 50 it
is loaded along ILRAM contents) */
/* Copy permanently-mapped code to start of user RAM (this section is
only used on fx-9860G; on fx-CG 50 it's fixed in ILRAM) */
void *rgmapped = mmu_uram();
regcpy(&lgmapped, &sgmapped, rgmapped);
@ -171,7 +167,6 @@ static int start2(int isappli, int optnum)
{
fixups[i] += (uint32_t)rgmapped;
}
#endif
/* Install gint, switch VBR and initialize drivers */
kinit();

View File

@ -9,6 +9,8 @@
** * File system, because it's a mess and we might ruin the ROM.
*/
#include <gint/config.h>
.text
/* Dynamic allocation */
@ -58,7 +60,7 @@
#define syscall(id) syscall_(id, syscall_table)
#ifdef FX9860G
#if GINT_OS_FX
/* Dynamic allocation */
@ -129,9 +131,9 @@ ___Reset:
syscall_table:
.long 0x80010070
#endif /* FX9860G */
#endif /* GINT_OS_FX */
#ifdef FXCG50
#if GINT_OS_CG
/* Dynamic allocation */
@ -209,4 +211,4 @@ ___Reset:
syscall_table:
.long 0x80020070
#endif /* FXCG50 */
#endif /* GINT_OS_CG */

View File

@ -1,7 +1,19 @@
#include <gint/config.h>
.global _gint_tlbh
.section .gint.tlbh, "ax"
.align 4
#if GINT_OS_FX
# define SYSCALL_TABLE 0x80010070
# define SYSCALL_TLBH 3
#elif GINT_OS_CG
# define SYSCALL_TABLE 0x80020070
# define SYSCALL_TLBH 12
#else
# error Unknown HW for tlbh.S!
#endif
_gint_tlbh:
sts.l pr, @-r15
stc.l gbr, @-r15
@ -28,16 +40,9 @@ test_tea:
map:
/* If TEA is mappable, map a page and return */
#ifdef FX9860G
mov #3, r0
#endif
#ifdef FXCG50
mov #12, r0
#endif
mov.l .syscall, r2
jsr @r2
nop
mov #SYSCALL_TLBH, r0
lds.l @r15+, macl
lds.l @r15+, mach
@ -73,12 +78,5 @@ panic:
.long 0x00300000
.max_mapped_rom:
.long 0x00300000 + _srom
#ifdef FX9860G
.syscall:
.long 0x80010070
#endif
#ifdef FXCG50
.syscall:
.long 0x80020070
#endif
.long SYSCALL_TABLE

View File

@ -8,7 +8,7 @@
#include <gint/gint.h>
#include <gint/defs/types.h>
#ifdef FX9860G
#if GINT_HW_FX
#include <gint/drivers/t6k11.h>
#endif
@ -49,7 +49,7 @@ key_event_t getkey_opt(int opt, volatile int *timeout)
continue;
}
#ifdef FX9860G
#if GINT_HW_FX
/* Backlight toggle */
if((opt & GETKEY_BACKLIGHT) && e.type == KEYEV_DOWN &&
((e.key == KEY_LIGHT) ||
@ -65,10 +65,8 @@ key_event_t getkey_opt(int opt, volatile int *timeout)
e.key == KEY_MENU && !e.shift && !e.alpha)
{
gint_osmenu();
#ifdef FXCG50
if(opt & GETKEY_MENU_DUPDATE)
dupdate();
#endif
if(!(opt & GETKEY_MENU_EVENT))
continue;

View File

@ -5,9 +5,10 @@
#include <gint/defs/types.h>
#include <gint/mpu/pfc.h>
#include <gint/hardware.h>
#include <gint/config.h>
/* This file is SH7705-only. */
#ifdef FX9860G
#if GINT_HW_FX
#define PFC SH7705_PFC
/* iokbd_delay() - wait a bit so that I/O can keep up
@ -162,4 +163,4 @@ void iokbd_scan(uint8_t *scan)
}
}
#endif /* FX9860G */
#endif /* GINT_HW_FX */

View File

@ -57,7 +57,7 @@ bool mmu_is_rom(void const *ptr)
// SH7705 TLB
//---
#ifdef FX9860G
#if GINT_HW_FX
/* tlb_addr() - get the P4 address of a TLB address entry */
GINLINE const tlb_addr_t *tlb_addr(uint way, uint E)

View File

@ -1,5 +1,6 @@
#include <gint/usb.h>
#include <gint/mpu/usb.h>
#include <gint/config.h>
#include <stdarg.h>
#include <endian.h>
@ -14,11 +15,12 @@
// SETUP requests
//---
#ifdef FX9860G
#define ID_PRODUCT 0x6101 /* fx-9860G II, Protocol 7.00, etc. */
#else
#define ID_PRODUCT 0x6102 /* fx-CP 400, fx-CG 50, Mass Storage, etc. */
#endif
/* 0x6101: fx-9860G II, Protocol 7.00, etc.
0x6102: fx-CP 400, fx-CG 50, Mass Storage, etc. */
#define ID_PRODUCT GINT_HW_SWITCH(0x6101, 0x6102)
#define DESC_PRODUCT GINT_HW_SWITCH( \
u"CASIO fx-9860G family on gint", \
u"CASIO fx-CG family on gint")
static usb_dc_device_t dc_device = {
.bLength = sizeof(usb_dc_device_t),
@ -54,22 +56,14 @@ static usb_dc_string_t dc_string0 = {
GCONSTRUCTOR static void set_strings(void)
{
#ifdef FX9860G
char const *serial_base = (void *)0x8000ffd0;
uint16_t const *product = u"CASIO fx-9860G family on gint";
#endif
#ifdef FXCG50
char const *serial_base = (void *)0x8001ffd0;
uint16_t const *product = u"CASIO fx-CG 50 family on gint";
#endif
char const *serial_base = (void *)GINT_OS_SWITCH(0x8000ffd0, 0x8001ffd0);
/* Convert the serial number to UTF-16 */
uint16_t serial[8];
for(int i = 0; i < 8; i++) serial[i] = serial_base[i];
dc_device.iManufacturer = usb_dc_string(u"CASIO Computer Co., Ltd", 0);
dc_device.iProduct = usb_dc_string(product, 0);
dc_device.iProduct = usb_dc_string(DESC_PRODUCT, 0);
dc_device.iSerialNumber = usb_dc_string(serial, 8);
}