mirror of
https://gitee.com/anod/open_agb_firm.git
synced 2025-05-06 13:54:09 +08:00
Compare commits
2 Commits
77a30eeec2
...
207506c1bb
Author | SHA1 | Date | |
---|---|---|---|
![]() |
207506c1bb | ||
![]() |
81b4d94649 |
@ -168,6 +168,8 @@ PrintConsole *consoleSelect(PrintConsole* console);
|
|||||||
*/
|
*/
|
||||||
PrintConsole* consoleInit(GfxLcd lcd, PrintConsole* console);
|
PrintConsole* consoleInit(GfxLcd lcd, PrintConsole* console);
|
||||||
|
|
||||||
|
PrintConsole *consoleGet(void);
|
||||||
|
|
||||||
/// Clears the screen by using iprintf("\x1b[2J");
|
/// Clears the screen by using iprintf("\x1b[2J");
|
||||||
void consoleClear(void);
|
void consoleClear(void);
|
||||||
|
|
||||||
|
@ -710,6 +710,12 @@ PrintConsole *consoleSelect(PrintConsole* console){
|
|||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
PrintConsole *consoleGet(void){
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
return currentConsole;
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
void consoleSetFont(PrintConsole* console, ConsoleFont* font){
|
void consoleSetFont(PrintConsole* console, ConsoleFont* font){
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
|
@ -1,205 +0,0 @@
|
|||||||
#include "types.h"
|
|
||||||
#include "arm11/drivers/lgyfb.h"
|
|
||||||
#include "arm11/drivers/interrupt.h"
|
|
||||||
#include "drivers/cache.h"
|
|
||||||
#include "drivers/corelink_dma-330.h"
|
|
||||||
#include "arm11/drivers/lcd.h"
|
|
||||||
#include "kevent.h"
|
|
||||||
|
|
||||||
|
|
||||||
static KHandle g_frameReadyEvent = 0;
|
|
||||||
|
|
||||||
// DMA330 docs don't tell you the recommended alignment so we assume it's bus width.
|
|
||||||
alignas(8) static u8 g_gbaFrameDmaProg[42] =
|
|
||||||
{
|
|
||||||
// All transfer settings for RGB8 at 360x240 to a 512x512 texture.
|
|
||||||
0xBC, 0x01, 0xE6, 0xC2, 0xB9, 0x00, // MOV CCR, SB15 SS64 SAF SP2 DB15 DS64 DAI DP2
|
|
||||||
0xBC, 0x00, 0x00, 0x10, 0x31, 0x10, // MOV SAR, 0x10311000
|
|
||||||
0xBC, 0x02, 0x00, 0x00, 0x20, 0x18, // MOV DAR, 0x18200000
|
|
||||||
0x35, 0x70, // FLUSHP 14
|
|
||||||
0x20, 0x1D, // LP 30
|
|
||||||
0x32, 0x70, // WFP 14, burst
|
|
||||||
0x22, 0x46, // LP 71
|
|
||||||
0x04, // LD
|
|
||||||
0x08, // ST
|
|
||||||
0x3C, 0x02, // LPEND
|
|
||||||
0x27, 0x70, // LDPB 14
|
|
||||||
0x08, // ST
|
|
||||||
0x56, 0x40, 0x0E, // ADDH DAR, 0xE40
|
|
||||||
0x38, 0x0E, // LPEND
|
|
||||||
0x13, // WMB
|
|
||||||
0x34, 0x00, // SEV 0
|
|
||||||
0x00 // END
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void gbaDmaIrqHandler(UNUSED u32 intSource)
|
|
||||||
{
|
|
||||||
DMA330_ackIrq(0);
|
|
||||||
DMA330_run(0, g_gbaFrameDmaProg);
|
|
||||||
|
|
||||||
// We can't match the GBA refreshrate exactly so keep the LCDs around 90%
|
|
||||||
// ahead of the GBA output which gives us a time window of around 1.6 ms to
|
|
||||||
// render the frame and hopefully reduces output lag as much as possible.
|
|
||||||
u32 vtotal;
|
|
||||||
if(REG_LCD_PDC0_VPOS > 414 - 41) vtotal = 415; // Slower than GBA.
|
|
||||||
else vtotal = 414; // Faster than GBA.
|
|
||||||
REG_LCD_PDC0_VTOTAL = vtotal;
|
|
||||||
|
|
||||||
signalEvent(g_frameReadyEvent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void patchDmaProg(const bool is240x160)
|
|
||||||
{
|
|
||||||
if(is240x160)
|
|
||||||
{
|
|
||||||
u8 *const prog = g_gbaFrameDmaProg;
|
|
||||||
|
|
||||||
// Adjust bursts. Needs to be 16 transfers for 240x160.
|
|
||||||
prog[2] = 0xF6;
|
|
||||||
prog[4] = 0xBD;
|
|
||||||
|
|
||||||
// Adjust outer loop count.
|
|
||||||
prog[21] = 20 - 1;
|
|
||||||
|
|
||||||
// Adjust inner loop count.
|
|
||||||
prog[25] = 44 - 1;
|
|
||||||
|
|
||||||
// Adjust gap skip.
|
|
||||||
*((u16*)&prog[34]) = 0x1980;
|
|
||||||
|
|
||||||
// Make sure the DMA controller can see the code.
|
|
||||||
flushDCacheRange(prog, sizeof(g_gbaFrameDmaProg));
|
|
||||||
}
|
|
||||||
// Else 360x240. Nothing to do.
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Scale matrix limitations:
|
|
||||||
* First pattern bit must be 1 and last 0 (for V-scale) or it loses sync with the DS/GBA input.
|
|
||||||
* Vertical scaling is fucked with identity matrix.
|
|
||||||
*
|
|
||||||
* Matrix ranges:
|
|
||||||
* in[-3] -1024-1023 (0xFC00-0x03FF)
|
|
||||||
* in[-2] -4096-4095 (0xF000-0x0FFF)
|
|
||||||
* in[-1] -32768-32767 (0x8000-0x7FFF)
|
|
||||||
* in[0] -32768-32767 (0x8000-0x7FFF)
|
|
||||||
* in[1] -4096-4095 (0xF000-0x0FFF)
|
|
||||||
* in[2] -1024-1023 (0xFC00-0x03FF)
|
|
||||||
*
|
|
||||||
* Note: At scanline start the in FIFO is all filled with the first pixel.
|
|
||||||
* Note: The first column only allows 1 non-zero entry.
|
|
||||||
* Note: Bits 0-3 of each entry are ignored by the hardware.
|
|
||||||
* Note: 16384 (0x4000) is the maximum brightness of a pixel.
|
|
||||||
* The sum of all entries in a column should be 16384 or clipping will occur.
|
|
||||||
* Note: The window of (the 6) input pixels is post-increment.
|
|
||||||
* When the matching pattern bit is 0 it does not move forward.
|
|
||||||
*/
|
|
||||||
static void setScaleMatrix(LgyFbScaler *const scaler, const u32 len, const u32 patt,
|
|
||||||
const s16 *in, const u8 inBits, const u8 outBits)
|
|
||||||
{
|
|
||||||
scaler->len = len - 1;
|
|
||||||
scaler->patt = patt;
|
|
||||||
|
|
||||||
// Calculate the maximum values for input and output sub pixels.
|
|
||||||
s32 inMax = (0xFF00u>>inBits) & 0xFFu; // Input bits in upper part.
|
|
||||||
inMax = (inMax == 0 ? 1 : inMax);
|
|
||||||
s32 outMax = (1u<<outBits) - 1;
|
|
||||||
outMax = (outMax == 0 ? 1 : outMax);
|
|
||||||
|
|
||||||
vu32 *out = &scaler->matrix[0][0];
|
|
||||||
const vu32 *const outEnd = out + 6 * 8;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// Correct the color range using the scale matrix hardware.
|
|
||||||
// For example when converting RGB555 to RGB8 LgyFb lazily shifts the 5 bits up
|
|
||||||
// so 0b00011111 becomes 0b11111000. But for maximum pixel brightness on the
|
|
||||||
// input we also want the maximum on the output (0b11111000 --> 0b11111111).
|
|
||||||
// This will fix it and distribute the colors evenly across the output range.
|
|
||||||
// Also round up because the hardware will ignore the first 4 bits.
|
|
||||||
const s32 mEntry = *in++;
|
|
||||||
*out++ = mEntry * outMax / inMax + 8;
|
|
||||||
} while(out < outEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
KHandle LGYFB_init(/*const bool isTop,*/ const ScalerCfg *const cfg)
|
|
||||||
{
|
|
||||||
// TODO: Support TWL sized frames and using both LgyFb engines.
|
|
||||||
const bool is240x160 = cfg->w == 240 && cfg->h == 160;
|
|
||||||
|
|
||||||
patchDmaProg(is240x160);
|
|
||||||
if(DMA330_run(0, g_gbaFrameDmaProg)) return 0;
|
|
||||||
|
|
||||||
// Create KEvent for frame ready signal.
|
|
||||||
KHandle frameReadyEvent = createEvent(false);
|
|
||||||
g_frameReadyEvent = frameReadyEvent;
|
|
||||||
|
|
||||||
LgyFb *const lgyFb = getLgyFbRegs(true);
|
|
||||||
lgyFb->size = LGYFB_SIZE(cfg->w, cfg->h);
|
|
||||||
lgyFb->stat = LGYFB_IRQ_MASK;
|
|
||||||
lgyFb->irq = 0;
|
|
||||||
lgyFb->alpha = 0xFF;
|
|
||||||
|
|
||||||
// TODO: Can't we just always do color corrections on h? Output differs between the 2 when both are active.
|
|
||||||
if(is240x160)
|
|
||||||
{
|
|
||||||
setScaleMatrix(&lgyFb->h, cfg->hLen, cfg->hPatt, cfg->hMatrix, 5, 8);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setScaleMatrix(&lgyFb->v, cfg->vLen, cfg->vPatt, cfg->vMatrix, 5, 8);
|
|
||||||
setScaleMatrix(&lgyFb->h, cfg->hLen, cfg->hPatt, cfg->hMatrix, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// With RGB8 output solid red and blue are converted to 0xF8 and green to 0xFA.
|
|
||||||
// The green bias exists on the whole range of green colors.
|
|
||||||
// Some results:
|
|
||||||
// RGBA8: Same as RGB8 but with useless alpha component.
|
|
||||||
// RGB8: Observed best format. Invisible dithering and best color accuracy.
|
|
||||||
// RGB565: A little visible dithering. Good color accuracy.
|
|
||||||
// RGB5551: Lots of visible dithering. Good color accuracy (a little worse than 565).
|
|
||||||
u32 cnt = LGYFB_DMA_EN | LGYFB_OUT_SWIZZLE | LGYFB_OUT_FMT_8880 | LGYFB_HSCALE_EN | LGYFB_EN;
|
|
||||||
if(!is240x160) cnt |= LGYFB_VSCALE_EN;
|
|
||||||
lgyFb->cnt = cnt;
|
|
||||||
|
|
||||||
IRQ_registerIsr(IRQ_CDMA_EVENT0, 13, 0, gbaDmaIrqHandler);
|
|
||||||
|
|
||||||
return frameReadyEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LGYFB_deinit(/*const bool isTop*/ void)
|
|
||||||
{
|
|
||||||
// Disable LgyFb engine, acknowledge IRQs (if any), kill DMA channel and flush the FIFO.
|
|
||||||
LgyFb *const lgyFb = getLgyFbRegs(true);
|
|
||||||
lgyFb->cnt = 0;
|
|
||||||
// Acknowledge IRQs here. Nothing to do since none are enabled.
|
|
||||||
DMA330_kill(0);
|
|
||||||
lgyFb->flush = 0;
|
|
||||||
|
|
||||||
// Unregister isr and delete event (if any was created).
|
|
||||||
IRQ_unregisterIsr(IRQ_CDMA_EVENT0);
|
|
||||||
if(g_frameReadyEvent != 0)
|
|
||||||
deleteEvent(g_frameReadyEvent);
|
|
||||||
g_frameReadyEvent = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LGYFB_stop(/*const bool isTop*/ void)
|
|
||||||
{
|
|
||||||
// Disable LgyFb engine, acknowledge IRQs (if any), kill DMA channel and flush the FIFO.
|
|
||||||
LgyFb *const lgyFb = getLgyFbRegs(true);
|
|
||||||
lgyFb->cnt &= ~LGYFB_EN;
|
|
||||||
// Acknowledge IRQs here. Nothing to do since none are enabled.
|
|
||||||
DMA330_kill(0);
|
|
||||||
lgyFb->flush = 0;
|
|
||||||
|
|
||||||
// Clear event to prevent issues since we just disabled LgyFb.
|
|
||||||
clearEvent(g_frameReadyEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LGYFB_start(/*const bool isTop*/ void)
|
|
||||||
{
|
|
||||||
// Restart DMA and then LgyFb.
|
|
||||||
if(DMA330_run(0, g_gbaFrameDmaProg)) return;
|
|
||||||
getLgyFbRegs(true)->cnt |= LGYFB_EN;
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of open_agb_firm
|
|
||||||
* Copyright (C) 2021 derrek, profi200
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
#include "ipc_handler.h"
|
|
||||||
#include "drivers/pxi.h"
|
|
||||||
#ifdef __ARM9__
|
|
||||||
#include "arm9/drivers/interrupt.h"
|
|
||||||
#include "arm9/drivers/ndma.h"
|
|
||||||
#elif __ARM11__
|
|
||||||
#include "arm11/fmt.h"
|
|
||||||
#include "arm11/drivers/interrupt.h"
|
|
||||||
#endif
|
|
||||||
#include "drivers/gfx.h"
|
|
||||||
#include "arm.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
noreturn void __fb_assert(const char *const str, u32 line)
|
|
||||||
{
|
|
||||||
enterCriticalSection();
|
|
||||||
|
|
||||||
#ifdef __ARM9__
|
|
||||||
// Get rid of the warnings.
|
|
||||||
(void)str;
|
|
||||||
(void)line;
|
|
||||||
PXI_sendCmd(IPC_CMD11_PANIC, NULL, 0);
|
|
||||||
#elif __ARM11__
|
|
||||||
ee_printf("Assertion failed: %s:%" PRIu32, str, line);
|
|
||||||
//PXI_sendCmd(IPC_CMD9_PANIC, NULL, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
#ifdef __ARM9__
|
|
||||||
const u32 color = RGB8_to_565(0, 0, 255)<<16 | RGB8_to_565(0, 0, 255);
|
|
||||||
NDMA_fill((u32*)FRAMEBUF_BOT_A_1, color, SCREEN_SIZE_BOT);
|
|
||||||
NDMA_fill((u32*)FRAMEBUF_BOT_A_2, color, SCREEN_SIZE_BOT);
|
|
||||||
#elif __ARM11__
|
|
||||||
__wfi();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,14 +13,14 @@ static atp_text_t stct = NULL;
|
|||||||
#define ATP_COLOR_SIZE (ATP_COLOR_WHITE+1)
|
#define ATP_COLOR_SIZE (ATP_COLOR_WHITE+1)
|
||||||
|
|
||||||
static uint16_t color_tbl[] = {
|
static uint16_t color_tbl[] = {
|
||||||
RGB8_to_565(0xc2, 0xcc, 0xd0), // 亮色
|
BGR8_2_565(0xc2, 0xcc, 0xd0), // 亮色
|
||||||
RGB8_to_565(0xff, 0x33, 0), // 红色
|
BGR8_2_565(0xff, 0x33, 0), // 红色
|
||||||
RGB8_to_565(0xaf, 0xdd, 0x22), // 绿色
|
BGR8_2_565(0xaf, 0xdd, 0x22), // 绿色
|
||||||
RGB8_to_565(0xfa, 0xff, 0x72), // 黄色
|
BGR8_2_565(0xfa, 0xff, 0x72), // 黄色
|
||||||
RGB8_to_565(0x4c, 0x8d, 0xb4), // 蓝色
|
BGR8_2_565(0x4c, 0x8d, 0xb4), // 蓝色
|
||||||
RGB8_to_565(0xe0, 0x00, 0x97), // 品红
|
BGR8_2_565(0xe0, 0x00, 0x97), // 品红
|
||||||
RGB8_to_565(0x21, 0xa6, 0x75), // 青色
|
BGR8_2_565(0x21, 0xa6, 0x75), // 青色
|
||||||
RGB8_to_565(0xf0, 0xfc, 0xff) // 白色
|
BGR8_2_565(0xf0, 0xfc, 0xff) // 白色
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------
|
//---------------------------------------------------
|
||||||
|
@ -532,7 +532,7 @@ cheat_error_t apply_cheat( int mode, u32 szrom, hookpoint_analyzer *analyzer, u1
|
|||||||
memset( hookpoint, 0, sizeof(hookpoint) );
|
memset( hookpoint, 0, sizeof(hookpoint) );
|
||||||
int n_hookpoint = 0;
|
int n_hookpoint = 0;
|
||||||
if( analyzer!=NULL && analyzer->provider != NULL )
|
if( analyzer!=NULL && analyzer->provider != NULL )
|
||||||
n_hookpoint = analyzer->provider( analyzer->caller_data, hookpoint );
|
n_hookpoint = analyzer->provider( analyzer->caller_data, (u32*)hookpoint );
|
||||||
if( n_hookpoint == 0 )
|
if( n_hookpoint == 0 )
|
||||||
n_hookpoint = rom_search_hookpoint( romdata, INSTR_LEN(realend) - 3, hookpoint ); // hook point need at least 3 instructions
|
n_hookpoint = rom_search_hookpoint( romdata, INSTR_LEN(realend) - 3, hookpoint ); // hook point need at least 3 instructions
|
||||||
if( n_hookpoint == 0 ) return CCHT_NO_IRQ;
|
if( n_hookpoint == 0 ) return CCHT_NO_IRQ;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user