[WIP] support of 'build-fx-as-cg' targeting the conversion of fx9860g based code to fxCGs prizm #25

Closed
Slyvtt wants to merge 12 commits from Slyvtt/gint:dev into dev
16 changed files with 611 additions and 30 deletions

View File

@ -245,8 +245,47 @@ set(SOURCES_CG
src/render-cg/image/image_p4_dye.c
)
set(ASSETS_FX src/font5x7.png)
set(ASSETS_CG src/font8x9.png)
set(SOURCES_FXASCG
# Gray engine
src/gray/gclear.c
src/gray/ggetpixel.c
src/gray/gint_gline.c
src/gray/gpixel.c
src/gray/grect.c
src/gray/gsubimage.c
src/gray/gtext.c
# Rendering
src/render-fx/bopti-asm-gray-scsp.s
src/render-fx/bopti-asm-gray.s
src/render-fx/bopti-asm-mono-scsp.s
src/render-fx/bopti-asm.s
src/render-fx/bopti.c
src/render-fx/dclear.c
src/render-fx/dgetpixel.c
src/render-fx/dpixel.c
src/render-fx/drect.c
src/render-fx/dsubimage.c
src/render-fx/gint_dline.c
src/render-fx/masks.c
src/render-fx/topti-asm.s
src/render-fx/topti.c
#special dupdate functions to treat a FX VRAM and convert to a CG VRAM
src/render-fxascg/dupdate.c
src/render-fxascg/engine_fxascg.c
# R61524 driver as we are working with a CG50
src/r61524/r61524.c
src/usb/classes/ff-bulk-gray.c
)
set(ASSETS_FX
src/font5x7.png
)
set(ASSETS_CG
src/font8x9.png
)
fxconv_declare_assets(${ASSETS_FX} ${ASSETS_CG})
include_directories(
@ -273,6 +312,17 @@ if("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
${LINKER_SCRIPTS})
endif()
if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G_G3A)
add_compile_options(-DFXCG50)
add_compile_definitions(FX9860G_AS_CG)
set(NAME "gint-fxg3a")
set(LINKER_SCRIPTS
"${CMAKE_CURRENT_BINARY_DIR}/fxcg50.ld"
"${CMAKE_CURRENT_BINARY_DIR}/fxcg50_fastload.ld")
add_library(gint-fxg3a STATIC ${SOURCES_COMMON} ${SOURCES_FXASCG} ${ASSETS_FX}
${LINKER_SCRIPTS})
endif()
set_target_properties("${NAME}" PROPERTIES OUTPUT_NAME "${NAME}")
# Generate linker scripts

View File

@ -105,6 +105,22 @@ The available options are:
% fxsdk build-cg install
```
**"Cross-Building" a fx-9860G II project for fx-CG 50**
fx-9860G II sources can be automatically converted to run on fx-CG 50, provided no
low level function/specific hardware manipulation/or syscall is used by the program.
The command is very similar to fx-9860G II one, except it is `fxsdk build-fx-as-cg`
instead of `fxsdk build-fx`.
The available options are:
```
% fxsdk build-fx-as-cg
% fxsdk build-fx-as-cg install
```
## Using in CMake-based add-ins
Find the `Gint` module and link against `Gint::Gint`. gint declares the include
@ -125,6 +141,10 @@ using the fxSDK, you will need to:
* Link with `-T fx9860g.ld -lgint-fx -lopenlibm -lc` on fx-9860G;
* Link with `-T fxcg50.ld -lgint-cg -lopenlibm -lc` on fx-CG 50.
Manually building a fx-9860G project to run on a fx-CG50 can be done :
* Build with `-m4-nofpu -mb -DFXCG50 -DFX9860G_AS_CG`;
* Link with `-T fxcg50.ld -lgint-fxascg -lopenlibm -lc`.
If you don't have a standard library such as
[Memallox's port of newlib](/PlaneteCasio/libc), you also need `-nostdlib`. I
typically use `-m3 -mb` or `-m4-nofpu -mb` to specify the platform, but that

View File

@ -7,6 +7,10 @@ elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G)
set(PC fx)
set(INTF_DEFN FX9860G)
set(INTF_LINK "-T;fx9860g.ld")
elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G_AS_CG)
set(PC fxascg)
set(INTF_DEFN FX9860G_AS_CG)
set(INTF_LINK "-T;fxcg50.ld")
else()
message(FATAL_ERROR "gint: unknown fxSDK platform '${FXSDK_PLATFORM}'")
endif()

View File

@ -5,14 +5,17 @@
configure:
@ fxsdk build-fx -c $(GINT_CMAKE_OPTIONS)
@ fxsdk build-cg -c $(GINT_CMAKE_OPTIONS)
@ fxsdk build-fx-as-cg -c $(GINT_CMAKE_OPTIONS)
build:
@ fxsdk build-fx
@ fxsdk build-cg
@ fxsdk build-fx-as-cg
install:
@ fxsdk build-fx install
@ fxsdk build-cg install
@ fxsdk build-fx-as-cg install
uninstall:
@ if [ -e build-fx/install_manifest.txt ]; then \
@ -21,5 +24,8 @@ uninstall:
@ if [ -e build-cg/install_manifest.txt ]; then \
xargs rm -f < build-cg/install_manifest.txt; \
fi
@ if [ -e build-fx-as-cg/install_manifest.txt ]; then \
xargs rm -f < build-fxascg/install_manifest.txt; \
fi
.PHONY: configure build install uninstall

View File

@ -20,7 +20,7 @@
#if defined(FX9860G)
# define GINT_HW_FX 1
# define GINT_HW_CG 0
#elif defined(FXCG50)
#elif defined(FXCG50) || defined(FX9860G_AS_CG)
# define GINT_HW_FX 0
# define GINT_HW_CG 1
#endif
@ -57,6 +57,10 @@
/* GINT_RENDER_DMODE: Selects whether the dmode override is available on
rendering functions. */
#define GINT_RENDER_DMODE GINT_HW_FX
#if defined(FX9860G_AS_CG)
# define GINT_RENDER_DMODE 1
#else
# define GINT_RENDER_DMODE GINT_HW_FX
#endif
#endif /* GINT_CONFIG */

View File

@ -15,7 +15,7 @@
#ifndef GINT_DISPLAY_CG
#define GINT_DISPLAY_CG
#ifdef FXCG50
#if defined(FXCG50) && !defined(FX9860G_AS_CG)
#ifdef __cplusplus
extern "C" {

View File

@ -9,7 +9,7 @@
#ifndef GINT_DISPLAY_FX
#define GINT_DISPLAY_FX
#ifdef FX9860G
#if defined(FX9860G) || defined(FX9860G_AS_CG)
#ifdef __cplusplus
extern "C" {

View File

@ -19,11 +19,11 @@ extern "C" {
/* Platform-specific functions include VRAM management and the definition of
the color_t type. */
#ifdef FX9860G
#if defined(FX9860G) || defined(FX9860G_AS_CG)
#include <gint/display-fx.h>
#endif
#ifdef FXCG50
#if defined(FXCG50) && ! defined(FX9860G_AS_CG)
#include <gint/display-cg.h>
#endif

View File

@ -44,12 +44,6 @@ extern usb_interface_t const usb_ff_bulk;
// Sending standard messages
//---
/* usb_fxlink_text(): Send raw text
Send a string; fxlink will display it in the terminal. This can be used to
back stdout/stderr. Sending lots of small messages can be slow; if that's a
problem, fill in message manually. If size is 0, uses strlen(text). */
void usb_fxlink_text(char const *text, int size);
/* usb_fxlink_screenshot(): Take a screenshot
This function sends a copy of the VRAM to fxlink. This is best used just
@ -63,6 +57,27 @@ void usb_fxlink_text(char const *text, int size);
display (it's usually slow and currently not even implemented). */
void usb_fxlink_screenshot(bool onscreen);
#if defined(FX9860G) || defined(FX9860G_AS_CG)
/* usb_fxlink_screenshot_gray(): Take a gray screenshot on fx-9860G
This function is similar to usb_fxlink_screenshot(), but it takes a gray
screenshot. It depends on the gray engine so if you use your add-in will
automatically have the gray engine, that's why it's separate. */
void usb_fxlink_screenshot_gray(bool onscreen);
#endif
/* usb_fxlink_text(): Send raw text
This function sends a string with the "text" type, which fxlink prints on
the terminal. It will send a full fxlink message (with a commit), which is
inefficient if there is a lot of text to send. For better speed, send the
message manually by filling the header and doing the writes and commit
manually.
This function sends the text by blocks of 4 bytes or 2 bytes when alignment
and size allow, and 1 byte otherwise. If size is 0, strlen(text) is used. */
void usb_fxlink_text(char const *text, int size);
/* usb_fxlink_videocapture(): Send a frame for a video recording
This function is essentially the same as usb_fxlink_screenshot(). It sends a
@ -74,12 +89,9 @@ void usb_fxlink_screenshot(bool onscreen);
automatically send new frames to fxlink. */
void usb_fxlink_videocapture(bool onscreen);
#ifdef FX9860G
/* Similar to usb_fxlink_screenshot(), but takes a gray screenshot if the gray
engine is currently running. */
void usb_fxlink_screenshot_gray(bool onscreen);
/* Like usb_fxlink_videocapture(), but uses VRAM data from the gray engine. */
#if defined(FX9860G) || defined(FX9860G_AS_CG)
/* usb_fxlink_videocapture_gray(): Send a gray frame for a video recording
Like usb_fxlink_videocapture(), but uses VRAM data from the gray engine. */
void usb_fxlink_videocapture_gray(bool onscreen);
#endif

View File

@ -11,7 +11,6 @@
//---
// Interrupt controllers
//---
GRODATA3 sh7705_intc_t const SH7705_INTC = {
.IPR = {
(void *)0xfffffee2, (void *)0xfffffee4,

View File

@ -26,7 +26,7 @@ extern uint32_t
lilram, silram, rilram, /* IL memory section */
lxyram, sxyram, rxyram, /* X and Y memory section */
sbss, rbss; /* User's BSS section */
#ifdef FX9860G
#if defined(FX9860G) && !defined(FX9860G_AS_CG)
extern uint32_t
lgmapped, sgmapped, /* Permanently mapped functions */
lreloc, sreloc; /* Relocatable references */
@ -136,7 +136,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 defined(FX9860G) && !defined(FX9860G_AS_CG)
if(isSH3())
{
/* Try to map every ROM address up to _srom */
@ -159,7 +159,7 @@ static int start2(int isappli, int optnum)
gint_load_onchip_sections();
#ifdef FX9860G
#if defined(FX9860G) && !defined(FX9860G_AS_CG)
/* Copy permanently-mapped code to start of user RAM (on fx-CG 50 it
is loaded along ILRAM contents) */
void *rgmapped = mmu_uram();

View File

@ -9,9 +9,16 @@
#include "topti-asm.h"
/* Default font */
extern font_t gint_font8x9;
font_t const * gint_default_font = &gint_font8x9;
font_t const * topti_font = &gint_font8x9;
#if(FX9860G_AS_CG)
extern font_t gint_font5x7;
font_t const * gint_default_font = &gint_font5x7;
font_t const * topti_font = &gint_font5x7;
#else
extern font_t gint_font8x9;
font_t const * gint_default_font = &gint_font8x9;
font_t const * topti_font = &gint_font8x9;
#endif
/* topti_glyph(): Render a glyph on the VRAM
Prints a glyph naively using word accesses, because for most fonts with a

137
src/render-fxascg/dupdate.c Normal file
View File

@ -0,0 +1,137 @@
#include <gint/display.h>
#include <gint/kmalloc.h>
#include <gint/config.h>
#include <gint/drivers/r61524.h>
#include "../render/render.h"
/* The destination VRAM for upscaling + centering + conversion B&W --> 16bits RGB565 */
uint16_t *cg_vram; // set to 0 at initialisation
/* Standard video RAM for fx9860g is 1 bit per pixel */
GALIGNED(32) static uint32_t fx_vram[256];
/* Here is the definition of the VRAM pointer, exposed in <gint/display.h> */
uint32_t *gint_vram = fx_vram;
/* The current rendering mode */
struct rendering_mode const *dmode = NULL;
bool dvram_init( void )
{
int const MARGIN = 32;
/* Leave MARGIN bytes on each side of the region; this enables some
important optimizations in the image renderer. We also add another
32 bytes so we can manually 32-align the region */
uint32_t region = (uint32_t)kmalloc(DWIDTH*DHEIGHT*2 + MARGIN*2 + 32,
#if !defined(GINT_NO_OS_STACK)
"_ostk"
#else
NULL
#endif
);
if(region == 0)
return false;
/* 32-align the region */
region = (region + 31) & -32;
/* Skip a MARGIN */
region += MARGIN;
/* Use an uncached address */
region = (region & 0x1fffffff) | 0xa0000000;
/* Don't enable triple buffering by default */
cg_vram = (void *)region;
return true;
}
void dgetvram(uint16_t **ptr_vram_1, uint16_t **ptr_vram_2)
{
if(ptr_vram_1) *ptr_vram_1 = cg_vram;
if(ptr_vram_2) *ptr_vram_2 = cg_vram;
}
void drawupscale( int x, int y, int color )
{
int u=y*396*3;
int v=x*3;
uint16_t colorcg;
if (color==C_WHITE) colorcg=0xFFFF;
else colorcg=0x0000;
int baseindex = (396*16+6+v+u); // 16 lines on top/bottom remain black and 6 columns on left/right remain black
cg_vram[baseindex] = colorcg;
cg_vram[baseindex+1] = colorcg;
cg_vram[baseindex+2] = colorcg;
baseindex+=396;
cg_vram[baseindex] = colorcg;
cg_vram[baseindex+1] = colorcg;
cg_vram[baseindex+2] = colorcg;
baseindex+=396;
cg_vram[baseindex] = colorcg;
cg_vram[baseindex+1] = colorcg;
cg_vram[baseindex+2] = colorcg;
}
/* dupdate(): Push the video RAM to the display driver */
void dupdate(void)
{
bool run_default = true;
if(dmode && dmode->dupdate)
{
/* Call the overridden dupdate(), but continue if it returns
non-zero (this is used when stopping the gray engine) */
int rc = dmode->dupdate();
run_default = (rc != 0);
}
if(run_default)
{
for( int j=0; j<DHEIGHT; j++ ) // 64 lines
{
for( int i=0; i<DWIDTH; i++ ) // 128 column
{
drawupscale( i, j, dgetpixel(i,j) ); // really not optimised; just to check if OK
}
}
//draw a black layer around the screen
int base1 = 0;
int base2 = (64*3+16)*396;
for(int u = 0; u<16; u++)
{
for(int v = 0; v<396; v++)
{
cg_vram[base1+v] = 0;
cg_vram[base2+v] = 0;
}
base1+=396;
base2+=396;
}
base1 = 16*396;
base2 = 16*396+6+128*3;
for(int u = 0; u<64*3; u++)
{
for(int v = 0; v<6; v++)
{
cg_vram[base1+v] = 0;
cg_vram[base2+v] = 0;
}
base1+=396;
base2+=396;
}
r61524_display(cg_vram, 0, 224, R61524_DMA_WAIT );
}
gint_call(dupdate_get_hook());
}
__attribute__((alias("dupdate")))
void _WEAK_dupdate(void);

View File

@ -0,0 +1,342 @@
//---
// gint:gray:engine - Core gray engine
//---
#include <gint/defs/types.h>
#include <gint/drivers/r61524.h>
#include <gint/gray.h>
#include <gint/display.h>
#include <gint/kmalloc.h>
#include <stdlib.h>
#include "../render/render.h"
#include "../render-fx/render-fx.h"
/* Three additional video RAMS, allocated statically if --static-gray was set
at configure time, or with malloc() otherwise. */
#ifdef GINT_STATIC_GRAY
GBSS static uint32_t gvrams[1][256];
#endif
uint16_t *cg_vram_gray;
/* two VRAMs: two to draw and two to display */
static uint32_t *vrams[2] = { NULL, NULL };
/* Whether the engine is scheduled to run at the next frame */
static int runs = 0;
extern struct rendering_mode const *dmode;
/* The alternate rendering mode structure used to override d*() */
static struct rendering_mode const gray_mode = {
.dupdate = gupdate,
.dclear = gclear,
.drect = grect,
.dpixel = gpixel,
.dgetpixel = ggetpixel,
.gint_dhline = gint_ghline,
.gint_dvline = gint_gvline,
.dtext_opt = gtext_opt,
.dsubimage = gsubimage,
};
static struct rendering_mode const gray_exit_mode = {
.dupdate = gupdate,
.dclear = NULL,
.drect = NULL,
.dpixel = NULL,
.dgetpixel = NULL,
.gint_dhline = NULL,
.gint_dvline = NULL,
.dtext_opt = NULL,
.dsubimage = NULL,
};
//---
// Engine control (init/quit and start/stop)
//---
//static int gray_int(void);
static void gray_quit(void);
/* gray_isinit(): Check whether the engine is initialized and ready to run */
static int gray_isinit(void)
{
//return (vrams[0] && vrams[1] && vrams[2] && vrams[3] && timer >= 0);
return (vrams[0] && vrams[1]);
}
bool dvram_init_gray( void )
{
int const MARGIN = 32;
/* Leave MARGIN bytes on each side of the region; this enables some
important optimizations in the image renderer. We also add another
32 bytes so we can manually 32-align the region */
uint32_t region = (uint32_t)kmalloc(DWIDTH*DHEIGHT*2 + MARGIN*2 + 32,
#if !defined(GINT_NO_OS_STACK)
"_ostk"
#else
NULL
#endif
);
if(region == 0)
return false;
/* 32-align the region */
region = (region + 31) & -32;
/* Skip a MARGIN */
region += MARGIN;
/* Use an uncached address */
region = (region & 0x1fffffff) | 0xa0000000;
/* Don't enable triple buffering by default */
cg_vram_gray = (void *)region;
return true;
}
/* gray_init(): Initialize the engine
This is done at startup so that memory can be reserved very early from the
heap (because not having enough memory is unrecoverable for the engine). */
GCONSTRUCTOR static void gray_init(void)
{
/* We need four VRAMs. First use the standard monochrome one */
vrams[0] = gint_vram;
#ifdef GINT_STATIC_GRAY
vrams[1] = gvrams[0];
#else
vrams[1] = malloc(1024);
#endif /* GINT_STATIC_GRAY */
dvram_init_gray();
/* On failure, release the resources that we obtained */
if(!gray_isinit()) gray_quit();
}
/* gray_quit(): Free engine resources */
GDESTRUCTOR static void gray_quit(void)
{
#ifndef GINT_STATIC_GRAY
if(vrams[1]) free(vrams[1]);
vrams[1] = NULL;
#endif /* GINT_STATIC_GRAY */
}
/* gray_start(): Start the gray engine */
static void gray_start(void)
{
runs = 1;
}
/* gray_stop(): Stop the gray engine */
static void gray_stop(void)
{
runs = 0;
}
//---
// Dynamic udpate and rendering mode
//---
/* dgray(): Start or stop the gray engine at the next dupdate() */
int dgray(int mode)
{
/* Stack of states for the push modes */
static uint8_t states[32] = { 0 };
static uint8_t current = 0;
if(mode == DGRAY_ON)
{
if(!gray_isinit()) return 1;
/* Set the display module's alternate rendering mode to
override rendering functions to use their g*() variant */
if(!dgray_enabled()) dmode = &gray_mode;
}
else if(mode == DGRAY_OFF)
{
/* Set the mode to a temporary one that only overrides
dupdate() so that we can stop the engine next frame */
if(dgray_enabled()) dmode = &gray_exit_mode;
}
else if(mode == DGRAY_PUSH_ON)
{
if(current >= 32) return 1;
states[current++] = dgray_enabled() ? DGRAY_ON : DGRAY_OFF;
return dgray(DGRAY_ON);
}
else if(mode == DGRAY_PUSH_OFF)
{
if(current >= 32) return 1;
states[current++] = dgray_enabled() ? DGRAY_ON : DGRAY_OFF;
return dgray(DGRAY_OFF);
}
else if(mode == DGRAY_POP)
{
/* Stay at 0 if the user's push/pop logic is broken */
if(current > 0) current--;
/* Switch to previous state */
return dgray(states[current]);
}
else return 1;
return 0;
}
/* convert the gray scale into RGB565 and draw in the virutal VRAMthe 3x3 pixels upscaled and centered */
void gdrawupscale( int x, int y, int color_fx )
{
int u=y*396*3;
int v=x*3;
uint16_t color_cg;
if (color_fx==C_WHITE) color_cg=0xFFFF;
else if (color_fx==C_LIGHT) color_cg=0xAD55;
else if (color_fx==C_DARK) color_cg=0x528A;
else color_cg=0x0000;
int baseindex = (396*16+6+v+u); // 16 lines on top/bottom remain black and 6 columns on left/right remain black
cg_vram_gray[baseindex] = color_cg; // draw 3 pixels side by side
cg_vram_gray[baseindex+1] = color_cg;
cg_vram_gray[baseindex+2] = color_cg;
baseindex+=396; // same for the line below (line #2)
cg_vram_gray[baseindex] = color_cg;
cg_vram_gray[baseindex+1] = color_cg;
cg_vram_gray[baseindex+2] = color_cg;
baseindex+=396; // same for the line below (line #3)
cg_vram_gray[baseindex] = color_cg;
cg_vram_gray[baseindex+1] = color_cg;
cg_vram_gray[baseindex+2] = color_cg;
}
/* gray_int(): Interrupt handler */
//int gray_int(void)
//{
// //t6k11_display(vrams[st ^ 2], 0, 64, 16);
// timer_reload(GRAY_TIMER, delays[(st ^ 3) & 1]);
//
// st ^= 1;
//
// return TIMER_CONTINUE;
//}
/* gupdate(): Push the current VRAMs to the screen */
int gupdate(void)
{
/* At the first gupdate(), start the engine */
if(dmode == &gray_mode && !runs)
{
gray_start();
}
/* At the last gupdate(), stop the engine */
else if(dmode == &gray_exit_mode)
{
gray_stop();
dmode = NULL;
return 1;
}
uint32_t *light, *dark;
dgray_getscreen(&light, &dark);
for( int j=0; j<DHEIGHT; j++ ) // 64 lines
{
for( int i=0; i<DWIDTH; i++ ) // 128 column
{
int offset = (j << 2) + (i >> 5);
uint32_t mask = 1 << (~i & 31);
int l = (light[offset] & mask) !=0 ? 1 : 0;
int d = (dark [offset] & mask) !=0 ? 1 : 0;
int color_fx = (d << 1) | l;
gdrawupscale( i, j, color_fx ); // really not optimised; just to check if OK
}
}
//draw a black layer around the screen
int base1 = 0;
int base2 = (64*3+16)*396;
for(int u = 0; u<16; u++)
{
for(int v = 0; v<396; v++)
{
cg_vram_gray[base1+v] = 0;
cg_vram_gray[base2+v] = 0;
}
base1+=396;
base2+=396;
}
base1 = 16*396;
base2 = 16*396+6+128*3;
for(int u = 0; u<64*3; u++)
{
for(int v = 0; v<6; v++)
{
cg_vram_gray[base1+v] = 0;
cg_vram_gray[base2+v] = 0;
}
base1+=396;
base2+=396;
}
r61524_display(cg_vram_gray, 0, 224, R61524_DMA_WAIT );
/* When the engine is running, swap frames */
return 0;
}
//---
// Query and configuration functions
//---
/* dgray_enabled(): Check whether gray mode is enabled */
int dgray_enabled(void)
{
return (dmode == &gray_mode);
}
/* dgray_setdelays(): Set the gray engine delays */
void dgray_setdelays(uint32_t light, uint32_t dark)
{
// delays[0] = light;
// delays[1] = dark;
}
/* dgray_getdelays(): Get the gray engine delays */
void dgray_getdelays(uint32_t *light, uint32_t *dark)
{
// if(light) *light = delays[0];
// if(dark) *dark = delays[1];
}
/* dgray_getvram(): Get the current VRAM pointers */
void dgray_getvram(uint32_t **light, uint32_t **dark)
{
if(light) *light = vrams[0];
if(dark) *dark = vrams[1];
}
/* dgray_getscreen(): Get the current screen pointers */
void dgray_getscreen(uint32_t **light, uint32_t **dark)
{
if(light) *light = vrams[0];
if(dark) *dark = vrams[1];
}

View File

@ -1,4 +1,4 @@
#ifdef FX9860G
#if defined(FX9860G) || defined(FX9860G_AS_CG)
#include <gint/usb.h>
#include <gint/usb-ff-bulk.h>

View File

@ -104,12 +104,12 @@ static void capture_vram(GUNUSED bool onscreen, char const *type)
void *source = gint_vram;
int size, format;
#ifdef FX9860G
#if defined(FX9860G) || defined(FX9860G_AS_CG)
size = 1024;
format = USB_FXLINK_IMAGE_MONO;
#endif
#ifdef FXCG50
#if defined(FXCG50) && !defined(FX9860G_AS_CG)
if(onscreen) {
uint16_t *main, *secondary;
dgetvram(&main, &secondary);