⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 po4tact.c

📁 一个不错的硬盘播放器程序,包含VFD显示程序,红外线遥控程序,硬盘读写程序,及解码程序等.
💻 C
📖 第 1 页 / 共 5 页
字号:
	po_shiftup.determine = po_shiftup.done = po_shiftup.inactive = 0;
	po_shiftdn.determine = po_shiftdn.done = po_shiftdn.inactive = 0;
    }
    if (PO4_SELECT(Temp))   po_select.determine = 1;
    if (PO4_AUDIO(Temp))    po_audio.determine = 1;
    if (PO4_MUTE(Temp))     po_mute.determine = 1;
    if (PO4_SCAN(Temp))     po_scan.determine = 1;
    if (PO4_VOCAL(Temp))    po_vocal.determine = 1;
    if (vocal_assist_on)    vocalAssist(PO4_MICIN(Temp));
    
#endif
	
    /* 
     * If we are in the middle of TACK switch debouncing/processing,
     * call the corresponding routine.
     */
#ifdef SVIDEO
    if (po_svideo.determine)	processSvideo(Temp);
#endif

#ifdef ZOOM
    if (po_zoom.determine)	processZoom(Temp);
#endif
#ifdef ECHO
    if (po_echoup.determine)	processEchoUp(Temp);
    if (po_echodn.determine)	processEchoDn(Temp);
#endif
    if (po_shiftup.determine)	processShiftUp(Temp);
    if (po_shiftdn.determine)	processShiftDn(Temp);
    if (po_resume.determine)	processResume(Temp);
    if (po_select.determine)	processSelect(Temp);
    if (po_audio.determine)	processAudio(Temp);
    if (po_mute.determine)	processMute(Temp);
    if (po_scan.determine)	processScan(Temp);
    if (po_vocal.determine)	processVocal(Temp);
    
    if (playMode & MODE_FAST)	processFastMode();
    if (playMode & MODE_SLOW)	processSlowMotion();

    usrCmd = 0;		/* For debugging only */

}


/* 
 * Vocal Assist function. If vocal assist is on, then we'll look at
 * the status of mic. If mic is on, then we'll play left channel only.
 * If mic is off, then we'll wait for 2 second and start to play
 * from both channels.
 *
 * Inputs: 
 *	micIn - mic is off (0); mic is on (1)
 */
PRIVATE void vocalAssist(int micIn)
{
    if (micIn) {	/* If there is voice in, turn off inside voice	*/
	last_voice_clock = glbTimer;
	vcx_audio_channel = LEFT_LEFT;
    } else {
	/* If mic is off for 2 seconds, then turn right channel on */
	if ((glbTimer - last_voice_clock) > TWO_SECOND) { /* 2 sec */
	    vcx_audio_channel = LEFT_RIGHT; /* Vocal with music */
	} else {
	    vcx_audio_channel = LEFT_LEFT; /* Mono without vocal */
	}
    }
}


/************************************************************************
 * Routines to handle receiving and transmission of IR signals.		*
 ************************************************************************/
/* 
 * Once we get a key code, we'll call the corresponding key handler.
 *
 * If we don't want the IR to be passed on to CD, then set corresponding
 * bit in tblKillIR[] (killIR is no longer set here because receiving
 * of data bar takes between 9 to 18 ms, which is not a very long duration.
 * If somebody hogs CPU for 20ms, then we may set 'killIR' too late, and
 * as a result, the key is received by the CD loader.
 */
void processKeycode()
{
    unsigned char keyCode;

    if (codeIR & 0x100) {
	/* There is a new code! */
	keyCode = codeIR & 0xff;
	codeIR = 0;
    } else return;

#ifdef GETKEYCODE
    /*
     * If we just want to display the key code, we'll execute the
     * following code.
     */
    debugOsd((unsigned short) keyCode);
#else
    /*
     * If tray is pushed in, we won't know. So it is not safe to
     * keep track of open/close status.
     */
#if 0
    if (stOpen) {
	/* When the tray is OPEN, only few keys have response */
	if (keyCode == IRKEY_EJECT)
	  procOpenClose();
	else if ((keyCode == IRKEY_PLAY) || (keyCode == IRKEY_PAUSE)) {
	    stOpen = 0;
	    procPlay();
	} else if (keyCode == IRKEY_PAUSE2) {
	    stOpen = 0;
	    procPause();
	} else		/* Other keys are ignored */
	  OUTOSD(OSD_FUNCTION_STATUS_REGION, msgError, msgError, 5);
	return;
    }
#endif

#ifdef ZOOM
    if (zoom_level) {
	/* reset zoom level if the key is not good for zoom */
	if ((keyCode != IRKEY_ZOOM) && (keyCode != IRKEY_ZOOM_UP) &&
	    (keyCode != IRKEY_ZOOM_LEFT) && (keyCode != IRKEY_ZOOM_DOWN) &&
	    (keyCode != IRKEY_ZOOM_RIGHT)) {
	    do zoom_out(); while (zoom_level);
	    CLEAROSD(OSD_PAUSE_REGION);	/* Clear ZOOM2 */
	}
    }
#endif

    switch (keyCode) {
      case IRKEY_1:	    procTrackNumber(1);		break;
      case IRKEY_2:	    procTrackNumber(2);		break;
      case IRKEY_3:	    procTrackNumber(3);		break;
      case IRKEY_4:	    procTrackNumber(4);		break;
      case IRKEY_5:	    procTrackNumber(5);		break;
      case IRKEY_6:	    procTrackNumber(6);		break;
      case IRKEY_7:	    procTrackNumber(7);		break;
      case IRKEY_8:	    procTrackNumber(8);		break;
      case IRKEY_9:	    procTrackNumber(9);		break;
      case IRKEY_10:	    procTrack10();		break;
      case IRKEY_10PLUS:    procTrack10Plus(1);		break;
      case IRKEY_DECVOL:    procVolumeDn();		break;
      case IRKEY_EJECT:	    procOpenClose();		break;
#ifdef BILINGUAL_OSD
      case IRKEY_FB:	    procFast("FB", MSG_c_fb, IRKEY_FB);	break;
      case IRKEY_FF:	    procFast("FF", MSG_c_ff, IRKEY_FF);	break;
#else
      case IRKEY_FB:	    procFast("FB", IRKEY_FB);	break;
      case IRKEY_FF:	    procFast("FF", IRKEY_FF);	break;
#endif
      case IRKEY_INCVOL:    procVolumeUp();		break;
      case IRKEY_INTRO:	    procIntro();		break;
      case IRKEY_NEXT:	    procNext();			break;
      case IRKEY_PAUSE2:
      case IRKEY_PAUSE:	    procPause();		break;
      case IRKEY_PLAY:	    procPlay();			break;
      case IRKEY_PREVIOUS:  procPrevious();		break;
#ifdef BROWSER1
      case IRKEY_BROWSER:    procBrowser();    		break;
#else
      case IRKEY_REM:	    procRemain();    		break;
#endif
      case IRKEY_REP:	    procRepeat();    		break;
      case IRKEY_RETURN:    procStop();			break;
      case IRKEY_SETAB:	    procAB(); 	   		break;
      case IRKEY_SLOW:	    procSlow();			break;
      case IRKEY_PBCON:	    procPBC();			break;
      case IRKEY_SURROUND:  procSpatial();		break;
      case IRKEY_VIDEO:	    procVideoMode();		break;
      case IRKEY_VIEW:	    procView();			break;
#ifdef ZOOM
      case IRKEY_ZOOM:	    po_zoom.determine = 1;	break;
#endif
#ifdef ECHO
      case IRKEY_ECHO_PLUS: po_echoup.determine = 1;	break;
      case IRKEY_ECHO_MINUS:po_echodn.determine = 1;	break;
#endif
      case IRKEY_KEYPLUS:   po_shiftup.determine = 1; 	break;
      case IRKEY_KEYMINUS:  po_shiftdn.determine = 1; 	break;
      case IRKEY_KEYRESUME: po_resume.determine = 1;  	break;
      case IRKEY_MODE:	    po_audio.determine = 1;	break;
      case IRKEY_MUTE:	    procMute();			break;
#ifdef BILINGUAL_OSD
      case IRKEY_OSD:	    procOsdLanguage();		break;
#endif
      default: 		    OUTOSD(OSD_FUNCTION_STATUS_REGION, msgError, 
				   msgError, 2);
								    	break;
    }
#endif	/* GETKEYCODE */
}

/************************************************************************
 * Routines to be called while inside fast/slow mode.			*
 ************************************************************************/
PRIVATE unsigned int last_send_time;
/* Send FF/FB signal to make the CD loader go faster	*/
PRIVATE void processFastMode()
{
    int i, currtime;

    if (vcx_pause_ack) {	/* Display I frame done	*/
	if (fast_key_num) {	/* enough ?		*/
	    currtime = (mvd[riface_timer2] >> 12) & 0xfffff; /* 1/16ms unit */
	    if (((currtime - last_send_time) & 0x7ff) >= 1500) {
		IR_send_data(fast_key, 0);
		last_send_time = currtime;
		fast_key_num --;
	    }
	} else {
	    vcx_interupt_FrameCount_pause = 0;
	    vcx_interupt_FrameCount = VID_frame_count + 1;
	    vcx_interupt_FrameCount_pause = VC_PAUSE;
	    vcx_playaudio_only = 0;	/* Start video decode again */
	    fast_key_num = FAST_KEY_NUM;
	    vcx_pause = vcx_pause_ack = 0;
	}
    }
}

/* Stop copying data to system buffer when buffer is near full,	*
 * and make the CD loader go back a little bit			*/
PRIVATE void processSlowMotion()
{
    int space_left;

    VBV_update_occupancy(space_left);
    space_left = VBV_size - space_left;

    if (XPORT_active) {
	if (space_left < 1500) {
	    XPORT_active = 0;
	    mvd[tdmctl0] = 0x400;		/* Kill TDM		*/
	    mvd[tdmrcvslots0] = 0;
	    mvd[xport_misc] = XPORT_RESET;	/* Kill transport	*/
	    IR_send_FB();
	}
    }

    if (!XPORT_active && (space_left > 7000)) {
	cleanSystemState();
	XPORT_active = 1;
    }
}

/************************************************************************
 * Routines called during initialization only.				*
 ************************************************************************/
/*
 * Get jumper values and set play varibles accordingly
 */
void CUST_init()
{
    unsigned int jumper;

    /*
     * AUX 0, 1, 4, 5, 6 are not outputs.
     */
    TRISTATE_AUX0;
    TRISTATE_AUX1;
    TRISTATE_AUX4;
    TRISTATE_AUX5;
    TRISTATE_AUX6;

    /* Set aux3 to '0' so that IR_IN can go through the external XOR 	*
     * gate because there is build-in XOR gate inside 3208		*/
    CLEAR_AUX3;

    changeTVmode(240);		/* Default TV mode is PAL		*/
    READ_HOSTPORT(jumper);
    jumperAuto	 = 0;				/* 0 is to auto detect	*/
    encSelMode   = TV_NTSC;

    vcx_xfer_mode = 5;		/* Data come from TDM			*/
    audio_in_digest = 1;
    resend_delay = THREE_SECOND;

    skipTk1	 = 1;				/* Skip tk1 for 1.1	*/
    vcx_cd_drive = CD_SONY;			/* Type of CD drive	*/
    vcx_osd_on	 = 1;				/* 0 is OSD on		*/
    sysIRcode	 = IR_SYSCODE;			/* Initialize sys code	*/

    audioLevel	 = AUDIO_INIT;			/* Initial audio level	*/
    /*
     * Initialize vcx_VertSz to match the initial TV mode. From here
     * on, if incoming data has a differnt VertSz and we are in AUTO
     * mode, we'll force the encoder mode to change.
     */
    vcx_VertSz	 = DISP_scn_height;

    displayLogo = 0;			/* We'll display it in top.c	*/
    showingLogo = SHOWING_POWERUPLOGO;	/* We'll be showing powerup logo*/

#ifdef SVIDEO
    DSC_s_video(svideo);		/* Default is composite only	*/
#endif
}


/************************************************************************
 * Utilities routines.							*
 ************************************************************************/
/*
 * Delay for 1/4 a second. Some of the CD controllers are not very good,
 * so we may want to wait for 1/4 a second before showing logo.
 */
PRIVATE void delayQuarterSec()
{
    unsigned int begTimer = glbTimer;
    do {
	/* 
	 * If we received a new key, then don't both to wait. Some new
	 * action will be taken.
	 */
	if (codeIR & 0x100)
	  break;
#ifdef ECHO
	MIC_service();
#endif
    } while((glbTimer - begTimer) < QUARTER_SECOND);
}


/*
 * This routine is called to detect whether we are playing or pausing.
 * There are two problems with pausing: 1) CD loader may not receive
 * PAUSE when we detect it; 2) Jiang Hai loaders are known to keep
 * on sending garbage data even in the pause state.
 *
 * Therefore, we do the following:
 * 1) If we think that we are pausing, we stop copying data from
 *    TDM buffer to system buffer but we keep on monitoring currCDtime.
 * 2) We continue monitor for a quarter second, during this time, we should
 *    have roughly 37.5 TDM interrupts with 18.75 currCDtime. If 80+%
 *    sectors have valid currCDtime, then we assume we are still
 *    playing (otherwise, we assume that we are really pausing.)
 * 3) If we are still playing, then reset flag so TDM data will be
 *    copied to the system buffer again.
 * 4) If a key is pressed while we are doing the detection, then we
 *    assume we are still playing (to avoid slow key detection problem.)
 *
 * This detection will only work for VCD data since CDDA does not have
 * currCDtime.
 *
 * Return:
 *	0: If we are pausing
 *	1: If we are playing
 *
 */
#ifdef JIANGHAI
PRIVATE int detectState()
{
    unsigned int endTimer;
    unsigned int prevtime = -1;
    int good = 0;
    
    /* End of monitoring period */
    endTimer = glbTimer + QUARTER_SECOND;
    do {
	if ((currCDtime != 0) && (currCDtime != prevtime)) {
	    /* This is a new SYNC and a valid currCDtime */
	    prevtime = currCDtime;
	    good++;
	}

	/* 
	 * If we receive a new key, while we are making detection, then
	 * assume we are still playing (i.e. forget about the 'PAUSE'
	 * key.
	 */
	if (codeIR & 0x100) return(0);
#ifdef ECHO
	MIC_service();
#endif
    } while (glbTimer < endTimer);

    return (good > 16);
}
#else
/*
 * For non-JiangHai loaders, I use zero detection. This is a "better"
 * way because it works for both video and audio CD's
 */
PRIVATE int detectState()
{
    unsigned int endTimer;
    unsigned int prevcnt = -1;
    int suspecious = 0;
    
    /* End of monitoring period */
    endTimer = glbTimer + QUARTER_SECOND;
    do {
	/* Xport requires baby sitting if we wait! */
	if (PO_newdata) startXport();
	if (XPORT_active) suspecious++;

	/* 
	 * If we receive a new key, while we are making detection, then
	 * assume we are still playing (i.e. forget about the 'PAUSE'
	 * key.
	 */
	if (codeIR & 0x100) return(0);
#ifdef ECHO
	MIC_service();
#endif
    } while (glbTimer < endTimer);

    return (suspecious > 1);
}
#endif


/*
 * Call detectState to see whether we are really pausing.
 *
 * NOTE: If the "smart" detection is not working properly, then just
 *       treat everything as CDDA (i.e. set tdmStopCopy then return 1)
 *
 * Return
 *	0: If we are NOT pausing
 *	1: If we are pausing
 */
PRIVATE int detectPause()
{
    unsigned int endTimer;

    /* Give loader a chance to catch up */
    endTimer = glbTimer + EIGHTH_SECOND;
    do {
#ifdef ECHO
	MIC_service();
#endif
    } while (glbTimer < endTimer);

#ifdef JIANGHAI
    tdmStopCopy = 1;		/* Stop copying to avoid noise		*/
    /*
     * There is no basis for gussing for CDDA data. We have to assume
     * that pause is properly done!
     */
    if (TDM_isCDDA) return(1);
#endif

    if (detectState()) {
	/* We are still playing */
	tdmStopCopy = 0;	/* Restart copying			*/
	return(0);
    } else return(1);
}

/*
 * Call detectState to see whether we are really playing
 *
 * NOTE: If the "smart" detection is not working properly, then just
 *       treat everything as CDDA (i.e. clear tdmStopCopy then return 1)
 *
 * Return
 *	0: If we are NOT playing
 *	1: If we are playing
 */
PRIVATE int detectPlay()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -