📄 vp.c
字号:
/* Copyright 1996, ESS Technology, Inc. *//* SCCSID @(#)vp.c 4.10 06/21/04 *//* * $Log$ */#include "common.h"#include "memmap.h"#include "mvd.h"#include "util.h"#include "vp.h"#include "const.h"#include "debug.h"#include "display.h"#include "vpucode.h"#include "low.h"#include "constvar.h"#include "vscale.h"#ifdef MP3#include "mp3.h"#endif/***************************************************************************** * compile option *****************************************************************************/#define PRINTF(a)/***************************************************************************** * Some local defines *****************************************************************************/#define VPRESETOFF 1#define VPLOADMODEON 2#define VPDMBASEMD 0x200#define VPZIGZAG 0x104#define VPPACKMD 0x102#if defined(UCODE_IN_DRAM) || defined(COMPRESS_MP3_UCODE)static int next_start;#endif#ifdef GAMMAextern int gamma_index;#endifvoid load_vp(RAMCODE, int, int);void register_ucode(RAMCODE, int *, int, int);static void register_all_ucode(void);#ifdef MP3void register_mp3_ucode(RAMCODE name, int *ucode, int size, int offset);static void register_all_mp3_ucode(void);#endif/***************************************************************************** Private data *****************************************************************************/RAMCODE RamCode = rnone; /* convey what is paged inside VP now */int ucode_start[rdummy]; /* addr of ucode in DRAM/SRAM */int ucode_size[rdummy]; /* ucode size in dwords */int ucode_offset[rdummy]; /* ucode offset from 0x800 in dwords */#ifndef UCODE_IN_DRAMRAMCODE ucode_in_dram0; /* What's in ucode cache 0 */RAMCODE ucode_in_dram1; /* What's in ucode cache 1 */int mru_ucode; /* Which page is most recently used */#endifDEBUGVAR(vp_load_error, 0);DEBUGVAR(loading_ucode, rnone);#if defined(MP3) && defined(VCDLC)void register_mp3_ucode(RAMCODE name, int *ucode, int size, int offset){#ifdef COMPRESS_MP3_UCODE /* ucode has already been decompressed to DRAM */ /* Load from DRAM */ ucode_start[name] = next_start; next_start += size; assert(next_start < MP3_UCODE_end);#else /* MP3 ucode is part of mp3 data segment */ ucode_start[name] = undram(ucode);#endif ucode_size[name] = size; ucode_offset[name] = offset;}static void register_all_mp3_ucode(void){#ifdef COMPRESS_MP3_UCODE next_start = MP3_UCODE_start; /* * NOTE: Since we currently compress mp3 vp-ucode in mktable.c, * the resulting decompressed ucode in DRAM is in the same * order specified in mktable.c. This requires that all * ucodes be "registered" in same order as in mktable.c. */#include "reg_vpuc.h" /* auto-generated by mktable.c */#else /* For LC code, MP3 ucode is part of MP3's data segment..not in ROM */ register_mp3_ucode(rmp3nonpage, mp3nonpage_ucode, mp3nonpage_SIZE, mp3nonpage_OFFSET); register_mp3_ucode(rmp3_destereo, mp3_destereo_ucode, destereo_SIZE, destereo_OFFSET); register_mp3_ucode(rmp3_mult48, mp3_mult48_ucode, mult48_SIZE, mult48_OFFSET); register_mp3_ucode(rmp3_imdct12, mp3_imdct12_ucode, imdct12_SIZE, imdct12_OFFSET); register_mp3_ucode(rmp3_imdct36, mp3_imdct36_ucode, imdct36_SIZE, imdct36_OFFSET);#endif /* COMPRESS_MP3_UCODE */}void load_mp3_vp(RAMCODE name){ #if 0 int code; int n = ucode_size[name]; int addr = ucode_offset[name]; code = ucode_start[name]; PRINTF(("Loading ucode %d at %d to 0x%x, %d dwords.\n", loading_ucode, code, addr, n)); VP_block_twice(NCMDQ_VP_block_twice, UCODE_IDLE); VP_cmdq_wait_empty; mvd[buscon_vp_control] = VPLOADMODEON | VPRESETOFF; asm("nop"); asm("nop"); asm("nop"); asm("nop"); mvd[buscon_cmdque_vpcbuswr] = 0x0100; /* loaducode write mode */ mvd[buscon_cmdque_vpcbuswr] = addr; VP_cmdq_deltas(n, 1); VP_cmdq_dmax(VPDMA_MEM2VP | a2x(code)); VP_cmdq_dmay(a2y(code)); VP_block_twice(NCMDQ_VP_block_twice, UCODE_IDLE); VP_cmdq_wait_empty; mvd[buscon_vp_control] = VPRESETOFF; asm("nop"); asm("nop"); asm("nop"); asm("nop"); /* keep these modes because the reset in loadvp will clear all these modes, causing video rla data to be transferred without zigzag translation */ mvd[buscon_cmdque_vpcbuswr] = (VPZIGZAG | VPPACKMD); mvd[buscon_cmdque_vpcbuswr] = VPDMBASEMD; /* no dm bank/word displacement */#else load_vp(name, 0, 1);#endif}void VP_load_mp3_ucode(RAMCODE name){ if (name == rnone) return; if (RamCode != name) { RamCode = rnone; DEBUGASSIGN(loading_ucode, name); load_mp3_vp(name); RamCode = name; }}#endif /* MP3 *//***************************************************************************** Register ucode. *****************************************************************************/void register_ucode(RAMCODE name, int *ucode, int size, int offset){#ifdef UCODE_IN_DRAM /* ucode has already been decompressed directly to DRAM */ /* Load from DRAM */ ucode_start[name] = next_start; next_start += size; assert(next_start < UCODE_end);#else ucode_start[name] = (int)ucode;#endif /* UCODE_IN_DRAM */ ucode_size[name] = size; ucode_offset[name] = offset;}/***************************************************************************** Load ucode to VP. We load from dram and use DMA. *****************************************************************************/void load_vp(RAMCODE name, int direct, int for_mp3){ int code; int n = ucode_size[name]; int addr = ucode_offset[name];#ifndef UCODE_IN_DRAM if (!direct && !for_mp3) { if (ucode_in_dram0 == name) { code = UCODE0_start; mru_ucode = 0; /* page 0 is now the most recently used */ } else if (ucode_in_dram1 == name) { code = UCODE1_start; mru_ucode = 1; /* page 1 is now the most recently used */ } else { /* Cache miss. Load to the least recently used page. */ if (name==rksearch) { code = ucode_start[name]; direct = 1; goto hack; } if (mru_ucode) { code = UCODE0_start; ucode_in_dram0 = rnone; } else { code = UCODE1_start; ucode_in_dram1 = rnone; } RISC_to_dram(code, (int *)ucode_start[name], ucode_size[name]); if (mru_ucode) { ucode_in_dram0 = name; mru_ucode = 0; } else { ucode_in_dram1 = name; mru_ucode = 1; } } } else#endif /* !UCODE_IN_DRAM */ { code = ucode_start[name]; } hack: PRINTF(("Loading ucode %d at %d to 0x%x, %d dwords.\n", loading_ucode,code,addr,n)); VP_block_twice(NCMDQ_VP_block_twice, UCODE_IDLE); VP_cmdq_wait_empty; mvd[buscon_vp_control] = VPLOADMODEON | VPRESETOFF; asm("nop"); asm("nop"); asm("nop"); asm("nop"); mvd[buscon_cmdque_vpcbuswr] = 0x0100; /* loaducode write mode */ mvd[buscon_cmdque_vpcbuswr] = addr; if (!direct || for_mp3) { VP_cmdq_deltas(n, 1); VP_cmdq_dmax(VPDMA_MEM2VP | a2x(code)); VP_cmdq_dmay(a2y(code)); } #ifndef UCODE_IN_DRAM else { int i; int *p = (int *)code; for (i=0; i<n; i++) { VP_cmdq_wait_empty; mvd[buscon_cmdque_vpdbuswrhi] = ((*p)>>16) & 0xffff; mvd[buscon_cmdque_vpdbuswrlow] = (*p++) & 0xffff; } VP_endio(0); }#endif VP_block_twice(NCMDQ_VP_block_twice, UCODE_IDLE); VP_cmdq_wait_empty; mvd[buscon_vp_control] = VPRESETOFF; asm("nop"); asm("nop"); asm("nop"); asm("nop"); /* keep these modes because the reset in loadvp will clear all these modes, causing video rla data to be transferred without zigzag translation */ mvd[buscon_cmdque_vpcbuswr] = (VPZIGZAG | VPPACKMD); mvd[buscon_cmdque_vpcbuswr] = VPDMBASEMD; /* no dm bank/word displacement */}/***************************************************************************** Register all ucode. *****************************************************************************/static void register_all_ucode(){#ifdef UCODE_IN_DRAM next_start = UCODE_start; /* * NOTE: Since we currently compress all the ucode in mktable.c, * the resulting decompressed ucode in DRAM is in the same * order specified in mktable.c. This requires that all * ucodes be "registered" in same order as in mktable.c. */#include "reg_vpuc.h" /* auto-generated by mktable.c */#else register_ucode(rksearch, T_ksearch_ucode, ksearch_SIZE, ksearch_OFFSET);#ifdef SPATIAL register_ucode(rspatial, T_spatial_ucode, spatial_SIZE, spatial_OFFSET);#endif register_ucode(rcdda, T_cdda_ucode, cdda_SIZE, cdda_OFFSET); register_ucode(rhscale, T_hscale_ucode, hscale_SIZE, hscale_OFFSET); register_ucode(rpal2ntsc, T_pal2ntsc_ucode, pal2ntsc_SIZE, pal2ntsc_OFFSET); register_ucode(rntsc2pal, T_ntsc2pal_ucode, ntsc2pal_SIZE, ntsc2pal_OFFSET); register_ucode(rtwo2one, T_two2one_ucode, two2one_SIZE, two2one_OFFSET); register_ucode(rvolume_128, T_volume_128_ucode, volume_128_SIZE, volume_128_OFFSET); #ifdef PRE_EMPHASIS register_ucode(rdemphasis, T_demphasis_ucode, demphasis_SIZE, demphasis_OFFSET);#endif#ifdef ECHO register_ucode(recho, T_echo_ucode, echo5_SIZE, echo5_OFFSET); #endif register_ucode(rmpgnonpage, T_mpgnonpage_ucode, mpgnonpage_SIZE, mpgnonpage_OFFSET);#if (defined GAMEBOY || defined CDG) register_ucode(rgamnonpage, T_gamnonpage_ucode, gamnonpage_SIZE, gamnonpage_OFFSET);#endif#ifdef EQUALIZER register_ucode(requnonpage, T_equnonpage_ucode, equnonpage_SIZE, equnonpage_OFFSET);#endif#ifdef KARASC register_ucode(rkscnonpage, T_kscnonpage_ucode, kscnonpage_SIZE, kscnonpage_OFFSET);#endif#ifdef REVERB register_ucode(rrvbnonpage, T_rvbnonpage_ucode, rvbnonpage_SIZE, rvbnonpage_OFFSET);#endif#ifdef MIC_RECORD register_ucode(rzeropoint, T_zeropoint_ucode, zeropoint_SIZE, zeropoint_OFFSET);#endif#if defined(MP3) && defined(VCDLC) /* For LC code, MP3 ucode is part of MP3's data segment..not in ROM */ register_all_mp3_ucode();#endif /* MP3 */ #endif /* UCODE_IN_DRAM */}#if defined(GSCALE) || defined(GAMMA) || defined(REVERB)/***************************************************************************** Retrieves VP ucode attributes *****************************************************************************/void VP_get_ucode_attr (RAMCODE name, unsigned short *size, unsigned short *offset, int *ramstart){ *size = ucode_size[name]; *offset = ucode_offset[name]; *ramstart = ucode_start[name];}void VP_ucode_reset(){ RamCode = rnone;}#endif /***************************************************************************** Initialise the VP. *****************************************************************************/void VP_init(int is_mp3){ VP_reset();#if defined(MP3) && defined(VCDLC) if (is_mp3) { register_all_mp3_ucode(); VP_load_mp3_ucode(rmp3nonpage); } else #endif { register_all_ucode();#ifdef GAMMA if(gamma_index!=7) Gamma_Vpcode_Pitch();#endif VP_load_ucode(rmpgnonpage); #ifndef UCODE_IN_DRAM ucode_in_dram0 = ucode_in_dram1 = rnone; mru_ucode = 1;#endif } VP_need_to_restore_ucode |= (VP_RESTORE_MPG_UCODE|VP_RESTORE_MP3_UCODE|VP_RESTORE_JPG_UCODE|\ VP_RESTORE_GSL_UCODE|VP_RESTORE_GAM_UCODE|VP_RESTORE_EQU_UCODE|\ VP_RESTORE_KSC_UCODE|VP_RESTORE_RVB_UCODE); VP_ucode(0, clr_pcstack); VP_ucode_wait();}/***************************************************************************** Make a wild guess. Don't need guess for chips later than 3210T. *****************************************************************************//* * Detect 3210 version by reading location 0x390 of VP microcode ROM. * * Different 3210 versions have different VP ucode address, so it is * extremely important to make sure the version number matches the chip. * Therefore, we'll do equality checking for all versions (no default), * and we'll loop until the version number matches. * */void VP_version() {#if 0 /* redundant..already set correctly in dispinfo.h and vscale.c */ /* No more old version of 3210! */ { extern DISP_Info disp_info[][4]; DISP_Info * dip = &disp_info[3][2]; /* B in PAL to PAL */ /* * Revision S or later (i.e. 3880). * (Revision T has the same ID, but it is NOT for production) * * Change B-frame Y/UV compression for PAL to PAL */ dip->zY = dip->zUV = 0x8000; /* -1 to 0x8000 */ } { extern VSCALE_Info vscale_info[]; VSCALE_Info * vip = &vscale_info[3]; /* B in PAL to PAL */ vip->ratio = 0x10; vip->ucode = rnone; }#endif}void VP_reset(){ volatile unsigned int *ptrdelay = (unsigned int *) bank3safe; mvd[buscon_vp_control] = 0; (void) *ptrdelay; mvd[buscon_vp_control] = VPRESETOFF; (void) *ptrdelay; mvd[buscon_cmdque_vpcbuswr] = (VPZIGZAG | VPPACKMD); mvd[buscon_cmdque_vpcbuswr] = VPDMBASEMD; /* no dm bank/word displacement */ mvd[buscon_cmdque_vpcbuswr]= loading; /* loading */ VP_cmdq_wait_empty; VP_ucode(0, clr_pcstack); VP_cmdq_wait_empty; RamCode = rnone; DEBUGASSIGN(loading_ucode, rnone);}/***************************************************************************** On the fly loading of VP ucode. Exported. *****************************************************************************/void VP_load_ucode(RAMCODE name){ if (name == rnone) return;#if !defined(UCODE_IN_DRAM) && (defined(GAMEBOY) || defined(CDG)) if (name == rgamnonpage) { load_vp(rgamnonpage, 1, 0); return; }#endif if (RamCode != name) { RamCode = rnone; DEBUGASSIGN(loading_ucode, name); load_vp(name, 0, 0); RamCode = name; }}/***************************************************************************** On the fly loading of VP ucode. Exported. *****************************************************************************/void VP_xfer_wait(void){ VP_block_twice(NCMDQ_VP_block_twice, UCODE_IDLE); VP_cmdq_wait_empty;}#ifdef REVERBvoid VP_set_rvb_delay_hack (void){ int i, j, k, del[4]; uint *dram_addr; ushort ucode_size, ucode_offset; int ucode_ramstart; VP_get_ucode_attr(rrvbnonpage, &ucode_size, &ucode_offset, &ucode_ramstart); dram_addr = (uint *)dram(ucode_ramstart); for (i = 0; i < 4; i++) { k = (i << 2); del[i] = (rvb_del[i] >> 2) - 1; if (del[i] > 11) del[i] = 11; for (j = 0; j < 4; j++) *(dram_addr + rvb_vp_offset[k + j]) = rvb_vp_code[del[i] * 4 + j]; } VP_ucode_reset(); if (VP_need_to_restore_ucode & VP_RESTORE_RVB_UCODE) { VP_load_ucode(rrvbnonpage); VP_need_to_restore_ucode &= ~VP_RESTORE_RVB_UCODE; VP_need_to_restore_ucode |= (VP_RESTORE_MPG_UCODE|VP_RESTORE_JPG_UCODE|VP_RESTORE_GAM_UCODE|\ VP_RESTORE_EQU_UCODE|VP_RESTORE_KSC_UCODE|VP_RESTORE_GSL_UCODE); }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -