mirror of
https://gitee.com/anod/open_agb_firm.git
synced 2025-05-07 06:14:12 +08:00
116 lines
3.7 KiB
C
116 lines
3.7 KiB
C
#pragma once
|
|
|
|
/*
|
|
* 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 <assert.h>
|
|
#include "types.h"
|
|
#include "mem_map.h"
|
|
#include "kevent.h"
|
|
|
|
|
|
#define LGYFB_TOP_REGS_BASE (IO_COMMON_BASE + 0x11000)
|
|
#define LGYFB_BOT_REGS_BASE (IO_COMMON_BASE + 0x10000)
|
|
|
|
#define LGYFB_TOP_FIFO *((const vu32*)(LGYFB_TOP_REGS_BASE + 0x200000))
|
|
#define LGYFB_BOT_FIFO *((const vu32*)(LGYFB_BOT_REGS_BASE + 0x200000))
|
|
|
|
typedef struct
|
|
{
|
|
vu32 len; // 0x00
|
|
vu32 patt; // 0x04
|
|
u8 _0x8[0x38];
|
|
vu32 matrix[6][8]; // 0x40
|
|
} LgyFbScaler;
|
|
|
|
typedef struct
|
|
{
|
|
vu32 cnt; // 0x000
|
|
vu32 size; // 0x004
|
|
vu32 stat; // 0x008
|
|
vu32 irq; // 0x00C
|
|
vu32 flush; // 0x010 Write 0 to flush LgyFb FIFO.
|
|
u8 _0x14[0xc];
|
|
vu32 alpha; // 0x020 8 bit alpha for all pixels.
|
|
u8 _0x24[0xcc];
|
|
vu32 unkF0; // 0x0F0
|
|
u8 _0xf4[0xc];
|
|
vu32 dithpatt0[2]; // 0x100 2 u32 regs with 4x2 pattern bits (mask 0xCCCC) each.
|
|
vu32 dithpatt1[2]; // 0x108 2 u32 regs with 4x2 pattern bits (mask 0xCCCC) each.
|
|
u8 _0x110[0xf0];
|
|
LgyFbScaler v; // 0x200
|
|
LgyFbScaler h; // 0x300
|
|
} LgyFb;
|
|
static_assert(offsetof(LgyFb, h.matrix[5][7]) == 0x3FC, "Error: Member h.matrix[5][7] of LgyFb is not at offset 0x3FC!");
|
|
|
|
ALWAYS_INLINE LgyFb* getLgyFbRegs(bool top)
|
|
{
|
|
return (LgyFb*)(top ? LGYFB_TOP_REGS_BASE : LGYFB_BOT_REGS_BASE);
|
|
}
|
|
|
|
|
|
// REG_LGYFB_CNT
|
|
#define LGYFB_EN (1u)
|
|
#define LGYFB_VSCALE_EN (1u<<1)
|
|
#define LGYFB_HSCALE_EN (1u<<2)
|
|
#define LGYFB_SPATIAL_DITHER_EN (1u<<4) // Unset behaves like weight 0xCCCC in both pattern regs.
|
|
#define LGYFB_TEMPORAL_DITHER_EN (1u<<5) // Unset behaves like weight 0xCCCC in both pattern regs.
|
|
#define LGYFB_OUT_FMT_8888 (0u)
|
|
#define LGYFB_OUT_FMT_8880 (1u<<8)
|
|
#define LGYFB_OUT_FMT_5551 (2u<<8)
|
|
#define LGYFB_OUT_FMT_5650 (3u<<8)
|
|
#define LGYFB_ROT_NONE (0u)
|
|
#define LGYFB_ROT_90CW (1u<<10)
|
|
#define LGYFB_ROT_180CW (2u<<10)
|
|
#define LGYFB_ROT_270CW (3u<<10)
|
|
#define LGYFB_OUT_SWIZZLE (1u<<12)
|
|
#define LGYFB_DMA_EN (1u<<15)
|
|
#define LGYFB_IN_FMT (1u<<16) // Use input format but this bit does nothing?
|
|
|
|
// REG_LGYFB_SIZE width and height
|
|
#define LGYFB_SIZE(w, h) (((h) - 1)<<16 | ((w) - 1))
|
|
|
|
// REG_LGYFB_STAT and REG_LGYFB_IRQ
|
|
#define LGYFB_IRQ_DMA_REQ (1u)
|
|
#define LGYFB_IRQ_BUF_ERR (1u<<1) // FIFO overrun?
|
|
#define LGYFB_IRQ_VBLANK (1u<<2)
|
|
#define LGYFB_IRQ_MASK (LGYFB_IRQ_VBLANK | LGYFB_IRQ_BUF_ERR | LGYFB_IRQ_DMA_REQ)
|
|
#define LGYFB_OUT_LINE(reg) ((reg)>>16) // STAT only
|
|
|
|
|
|
typedef struct
|
|
{
|
|
u16 w;
|
|
u16 h;
|
|
u8 vLen;
|
|
u8 vPatt;
|
|
s16 vMatrix[8 * 6];
|
|
// TODO: DMA output address?
|
|
u8 hLen;
|
|
u8 hPatt;
|
|
s16 hMatrix[8 * 6];
|
|
// TODO: DMA output address?
|
|
} ScalerCfg;
|
|
|
|
|
|
|
|
KHandle LGYFB_init(/*const bool isTop,*/ const ScalerCfg *const cfg); // Returns frame ready KEvent.
|
|
void LGYFB_deinit(/*const bool isTop*/ void);
|
|
void LGYFB_stop(/*const bool isTop*/ void);
|
|
void LGYFB_start(/*const bool isTop*/ void);
|