📄 po4tact.c
字号:
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 + -