buffer.c
来自「ESS3890+SL原代码(1*16内存)」· C语言 代码 · 共 892 行 · 第 1/2 页
C
892 行
/* Copyright 1996, ESS Technology, Inc. *//* SCCSID @(#)buffer.c 4.15 12/09/04 *//* * $Log$ */#include "vcxi.h"#include "vp.h"#include "memmap.h"#include "debug.h"#include "util.h"#include "low.h"#include "buffer.h"#include "tdm.h"#include "xport.h"#include "mpeg1vid.h"#include "mpgaudio.h"#ifdef ECHO#include "echo.h"#endif#ifdef SPATIAL#include "kara.h"#endif#ifdef PRE_EMPHASIS#include "const.h"#endif#if (defined(CDG) || defined(CD_TEXT))#include "cd_text.h"#endif#ifdef TRACE_MP3_AUDIOBREAK#include "mp3.h"#endif/**************************************************************************** Local defines. ****************************************************************************/#ifdef JPEG_DEC#define CONDITION_FOR_HUFDECA_XFER (!is_jpeg && !TDM_isCDDA && !ABV_draining)#define CONDITION_FOR_HUFDECA_EXIT (is_jpeg || TDM_isCDDA)#else#define CONDITION_FOR_HUFDECA_XFER (!TDM_isCDDA && !ABV_draining)#define CONDITION_FOR_HUFDECA_EXIT (TDM_isCDDA)#endif /* JPEG_DEC */#define done_but_needed(ch) \ ((!buscon_is_running(ch))&&(mask & buscon_##ch##_runbit))#undef DUMP_VBV_WHEN_FULL/**************************************************************************** Debugging. ****************************************************************************/#ifndef ECHOKEYDEBUGVAR(PCM_starvings, 0); /* Number of times PCM starved */#endifKEYDEBUGVAR(ABV_overflow, 0); /* Number of times ABV overflowed */KEYDEBUGVAR(VBV_overflow, 0); /* Number of times VBV overflowed */#define PRINTF(a)/**************************************************************************** Local function prototypes. ****************************************************************************//**************************************************************************** Local variables. ****************************************************************************/#define is_TDM 1/****************************************************************************** If there's enough room in DRAM initiate a xport buscon to sys buff. rdptr == wrptr means buffer empty. In the case of TDM we do it anyway. ******************************************************************************/#ifdef XFER_USE_MACRO#define xportv_xfer_TDM() do { \ int space = VBV_rdptr - VBV_wrptr; \ if (space <= 0) space += VBV_size; \ if (space <= VBV_write) { \ oh_my(0x16); \ KEYDEBUGINC(1, VBV_overflow); \ DBG_log_error(99, 1, space, VID_decoding_in_progress, 0, 0); \ VBV_rdptr = VBV_wrptr; \ } \ buscon_xfer(xportv, BDMA_USEDX, VBV_wrptr, VBV_write, 1); \} while (0)#define xporta_xfer_TDM() do { \ int i; \ int space = ABV_rdptr - ABV_wrptr; \ if (space <= 0) space += ABV_size; \ if (space <= ABV_write) { \ oh_my(0x17); \ KEYDEBUGINC(1, ABV_overflow); \ DBG_log_error(99, 2, space, VID_decoding_in_progress, 0, 0); \ ABV_wrptr = ABV_rdptr; \ for (i = 0; i < 2; i++) { \ ABV_wrptr += ABV_write; \ if (ABV_wrptr >= ABV_end) ABV_wrptr = ABV_start; \ } \ ABV_wrptr_save = ABV_wrptr; \ BUF_ABV_overflow = 1; \ } \ buscon_xfer(xporta, BDMA_USEDX, ABV_wrptr, ABV_write, 1); \ ABV_xfer_flag = 1; \} while (0)#elsevoid xportv_xfer_TDM(){ int space = VBV_rdptr - VBV_wrptr; if (space <= 0) space += VBV_size; if (space <= VBV_write) { oh_my(0x16); KEYDEBUGINC(1, VBV_overflow); DBG_log_error(99, 1, space, VID_decoding_in_progress, 0, 0); VBV_rdptr = VBV_wrptr; } buscon_xfer(xportv, BDMA_USEDX, VBV_wrptr, VBV_write, 1);}void xporta_xfer_TDM(){ int i; int space = ABV_rdptr - ABV_wrptr; if (space <= 0) space += ABV_size; if (space <= ABV_write) { oh_my(0x17); KEYDEBUGINC(1, ABV_overflow); DBG_log_error(99, 2, space, VID_decoding_in_progress, 0, 0); /* * Keep 2*ABV_write data in ABV so hufdeca can continue until * the next time we get into mpgaudio. */ ABV_wrptr = ABV_rdptr; for (i = 0; i < 2; i++) { ABV_wrptr += ABV_write; if (ABV_wrptr >= ABV_end) ABV_wrptr = ABV_start; } ABV_wrptr_save = ABV_wrptr; BUF_ABV_overflow = 1; } buscon_xfer(xporta, BDMA_USEDX, ABV_wrptr, ABV_write, 1); ABV_xfer_flag = 1;}#endif#define xportv_xfer() do { \ if (is_TDM) xportv_xfer_TDM(); \ else xportv_xfer_non_TDM(); \} while (0);#define xporta_xfer() do { \ if (is_TDM) xporta_xfer_TDM(); \ else xporta_xfer_non_TDM(); \} while (0);#ifdef JPEG_DECvoid xportv_xfer_no_macro() { xportv_xfer(); }#endif/****************************************************************************** Just finished a xport buscon to sys buff. Update sys buff write ptr. If xfer to huffdec is not running, start a new one. ******************************************************************************/#ifdef DUMP_VBV_WHEN_FULL#define VBV_wrap() do { \ static int fp = -1; \ fp = DBG_dump_memory((char *)dram(VBV_start), 4*VBV_size, fp, "video.bit");\ VBV_wrptr = VBV_start; \} while (0)#else#define VBV_wrap() VBV_wrptr = VBV_start#endif#ifdef DUMP_ABV_WHEN_FULL#define ABV_wrap() do { \ static int fp = -1; \ fp = DBG_dump_memory((char *)dram(ABV_start), 4*ABV_size, fp, "audio.bit");\ ABV_wrptr = ABV_start; \} while (0)#else#define ABV_wrap() ABV_wrptr = ABV_start#endif#ifdef WATCHDOG#define xportv_xfer_end() do { \ VBV_wrptr += VBV_write; \ VBV_ABV_xport_xfer_count++; \ if (VBV_wrptr == VBV_end) VBV_wrap(); \ DBG_log_buffer(20, VBV_write, VBV_wrptr, VBV_rdptr, 0, 0); \ if (!VBV_draining) { \ hufdecv_xfer(); \ if (VBV_draining) buscon_irq_enable(buscon_hufdecv_runbit); \ } \} while (0)#define xporta_xfer_end() do { \ ABV_wrptr += ABV_write; \ VBV_ABV_xport_xfer_count++; \ if (ABV_wrptr == ABV_end) ABV_wrap(); \ oh_my(0x10); \ DBG_log_buffer(21, ABV_write, ABV_wrptr, ABV_rdptr, 0, 0); \ if (CONDITION_FOR_HUFDECA_XFER) { \ hufdeca_xfer(); \ if (ABV_draining) buscon_irq_enable(buscon_hufdeca_runbit); \ } \} while (0)#else#define xportv_xfer_end() do { \ VBV_wrptr += VBV_write; \ if (VBV_wrptr == VBV_end) VBV_wrap(); \ DBG_log_buffer(20, VBV_write, VBV_wrptr, VBV_rdptr, 0, 0); \ if (!VBV_draining) { \ hufdecv_xfer(); \ if (VBV_draining) buscon_irq_enable(buscon_hufdecv_runbit); \ } \} while (0)#define xporta_xfer_end() do { \ ABV_wrptr += ABV_write; \ if (ABV_wrptr == ABV_end) ABV_wrap(); \ oh_my(0x10); \ DBG_log_buffer(21, ABV_write, ABV_wrptr, ABV_rdptr, 0, 0); \ if (CONDITION_FOR_HUFDECA_XFER) { \ hufdeca_xfer(); \ if (ABV_draining) buscon_irq_enable(buscon_hufdeca_runbit); \ } \} while (0)#endif/****************************************************************************** If there's enough data in sys buff and we're not CDDAing, initiate a xfer to huffdec, ******************************************************************************/#ifdef XFER_USE_MACRO#define hufdecv_xfer() do { \ int data = VBV_wrptr - VBV_rdptr; \ if (data < 0) data += VBV_size; \ if (data >= VBV_read) { \ buscon_xfer(hufdecv, BDMA_USEDX, VBV_rdptr, VBV_read, 1); \ VBV_draining = 1; \ } else { \ VBV_draining = 0; \ } \} while (0)#define hufdeca_xfer() do { \ int data; \ if (CONDITION_FOR_HUFDECA_EXIT) break; \ data = ABV_wrptr - ABV_rdptr; \ if (data < 0) data += ABV_size; \ if (data >= ABV_read) { \ buscon_xfer(hufdeca, BDMA_USEDX, ABV_rdptr, ABV_read, 1); \ ABV_draining = 1; \ } else { \ ABV_draining = 0; \ } \} while (0)#elsevoid hufdecv_xfer(){ int data = VBV_wrptr - VBV_rdptr; if (data < 0) data += VBV_size; if (data >= VBV_read) { buscon_xfer(hufdecv, BDMA_USEDX, VBV_rdptr, VBV_read, 1); VBV_draining = 1; } else { VBV_draining = 0; }}void hufdeca_xfer(){ int data; if (CONDITION_FOR_HUFDECA_EXIT) return; data = ABV_wrptr - ABV_rdptr; if (data < 0) data += ABV_size; if (data >= ABV_read) { buscon_xfer(hufdeca, BDMA_USEDX, ABV_rdptr, ABV_read, 1); ABV_draining = 1; } else { ABV_draining = 0; }}#endif/****************************************************************************** Just finished a xfer to huffdec. Update sys buff read ptr. If xport buscon is not running, start a new one. ******************************************************************************/#ifdef WATCHDOG #define hufdecv_xfer_end() do { \ VBV_rdptr += VBV_read; \ VBV_ABV_huffman_xfer_count++; \ if (VBV_rdptr == VBV_end) { \ VBV_rdptr = VBV_start; \ VBV_wrap_count++; \ } \ if (!VBV_filling) { \ xportv_xfer(); \ if (VBV_filling) buscon_irq_enable(buscon_xportv_runbit); \ } \} while (0)#define hufdeca_xfer_end() do { \ if (CONDITION_FOR_HUFDECA_EXIT) break; \ ABV_rdptr += ABV_read; \ VBV_ABV_huffman_xfer_count++; \ if (ABV_rdptr == ABV_end) ABV_rdptr = ABV_start; \ if (!ABV_filling) { \ xporta_xfer(); \ if (ABV_filling) buscon_irq_enable(buscon_xporta_runbit); \ } \} while (0)#else#define hufdecv_xfer_end() do { \ VBV_rdptr += VBV_read; \ if (VBV_rdptr == VBV_end) { \ VBV_rdptr = VBV_start; \ VBV_wrap_count++; \ } \ if (!VBV_filling) { \ xportv_xfer(); \ if (VBV_filling) buscon_irq_enable(buscon_xportv_runbit); \ } \} while (0)#define hufdeca_xfer_end() do { \ if (CONDITION_FOR_HUFDECA_EXIT) break; \ ABV_rdptr += ABV_read; \ if (ABV_rdptr == ABV_end) ABV_rdptr = ABV_start; \ if (!ABV_filling) { \ xporta_xfer(); \ if (ABV_filling) buscon_irq_enable(buscon_xporta_runbit); \ } \} while (0)#endif#ifdef JPEG_DECstatic int VBV_wrptr_save;/**************************************************************************** Kill the video xport buscon, then restart it again. If we don't have video huffdec buscon at this moment, kick it off. ****************************************************************************/void VBV_flush_gateway(void){ if (dont_need_flush_video) return; VBV_stop_filling(); VBV_wrptr_save = VBV_wrptr; VBV_start_filling(); if (!VBV_draining) VBV_start_draining();}/**************************************************************************** Kill the video huffdec buscon, then restart it again. If we don't have video xport buscon at this moment, kick it off. ****************************************************************************/void VBV_flush_cleanup(void){ if (dont_need_flush_video) return; buscon_zap(hufdecv); VBV_draining = 0; VBV_rdptr = VBV_wrptr_save; VBV_fullness = VBV_wrptr - VBV_rdptr; if (VBV_fullness < 0) VBV_fullness += VBV_size; VBV_start_draining(); if (!VBV_filling) VBV_start_filling();}#endif JPEG_DEC/**************************************************************************** Set various VBV/ABV operating parameters. In TDM mode a new xport buscon is started when the previous one finishes, no matter what. The system buffer will overflow if we're draining it too slow. Also when decoding from a file we disable the overflow-prevention mechanism. ****************************************************************************/void VBV_ABV_set_parameters(int xfer_mode){ if (xfer_mode==0) { VBV_alarm = 0; }}/**************************************************************************** Start xportv buscon for the first time. For TDM once we start a xport buscon it self-sustains forever. ****************************************************************************/void VBV_start_filling(void){ xportv_xfer(); buscon_irq_enable(buscon_xportv_runbit); if (is_TDM) VBV_filling = 1;}/**************************************************************************** Start xporta buscon for the first time. For TDM once we start a xport buscon it self-sustains forever. ****************************************************************************/void ABV_start_filling(void){ xporta_xfer(); buscon_irq_enable(buscon_xporta_runbit); if (is_TDM) ABV_filling = 1;}#ifndef VCDLCvoid ABV_start_draining(void){ hufdeca_xfer(); if (ABV_draining) { buscon_irq_enable(buscon_hufdeca_runbit); }}#endif/**************************************************************************** Start hufdecv_xfer for the first time. This is only used in the power-up logo whence we fill the VBV manually. ****************************************************************************/void VBV_start_draining(void){ hufdecv_xfer(); if (VBV_draining) { buscon_irq_enable(buscon_hufdecv_runbit); } else { assert(0); }}/**************************************************************************** Kill the audio xport buscon. You should first stop the xport before doing this. We will flush the xport fifo and then the gateway fifo,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?