📄 xport.c
字号:
void XPORT_restore_e0_c0(){ int *pid_data = T_pid_MPEG1_PS; mvd[xport_misc] = XPORT_LDPID | XPORT_RESET; mvd[xport_pid_table + XPORT_PID_E0] = pid_data[XPORT_PID_E0]; mvd[xport_pid_table + XPORT_PID_C0] = pid_data[XPORT_PID_C0]; mvd[xport_misc] = XPORT_RESET;}#endif/**************************************************************************** Select xport type, load ucode and cam. ****************************************************************************/#define set_parameter(a) { \ uCode= T_uCode##a; \ uCsize = T_uCode##a##_SZ/sizeof(int); \ pid = T_pid##a; \ pidsize = T_pid##a##_SZ/sizeof(int); \} /***************************************************************************** Select xport ucode based on xport_type. If xport_type == MULTI_XPORT, prompt user. Load xport ucode and cam table. Low level initialisation of the xport hardware. *****************************************************************************/int XPORT_init(int xport_type, int xfer_mode){ int *uCode; int *pid; int uCsize; int pidsize; int mode; if (xport_type == MULTI_XPORT) xport_type = vcx_bitstream_type;#if (MPEG1 && MKROM) set_parameter(_MPEG1_PS); /* VCD product */#else switch (xport_type) {#ifdef MPEG1 case MPEG1_PS: set_parameter(_MPEG1_PS); break;#endif case VIDEO_ELM_ONLY: set_parameter(_VIDEO_ELM_ONLY); break; case AUDIO_ELM_ONLY: set_parameter(_AUDIO_ELM_ONLY); break;#ifdef MPEG2 case DSS_SIMPLE: set_parameter(_DSS_SIMPLE); break; case DVD_SIMPLE: xport_video = 0; case PS_SIMPLE: set_parameter(_DVD_SIMPLE); break;#endif default: FATAL(("Unknown xport type %d\n", xport_type)); }#endif XPORT_load_ucode(uCode, uCsize); /* Select video/audio channel ID */#ifdef MPEG2 if (xport_type >= DSS_SIMPLE) { if (xport_video == -1) { printf("Video stream id: "); scanf("%d",&xport_video); } if(xport_audio== -1){ printf("Audio stream id: "); scanf("%d",&xport_audio); } if (xport_type != DSS_SIMPLE) { pid[0] = xport_video | 0x1e0; if (xport_type==DVD_SIMPLE) { pid[1] = 0x1bd;#ifdef SUB_PICTURE patch_xport_ucode(AID_CHECK, (uCode[AID_CHECK] & 0x7ffff00) | 0x20 | xport_audio); printf("Xport ucode at 0x%x changed from 0x%08x to 0x%08x.\n", AID_CHECK, uCode[AID_CHECK], (uCode[AID_CHECK] & 0x7ffff00) | 0x20 | xport_audio); /* Bypass the code that eat the 3 AC3 extra bytes by a "goto continue". */ patch_xport_ucode(SP_BYPASS, 0x3f00000 | (CONTINUE<<8)); printf("Xport ucode at 0x%x changed from 0x%08x to 0x%08x.\n", SP_BYPASS, uCode[SP_BYPASS], 0x3f00000 | (CONTINUE<<8));#else patch_xport_ucode(AID_CHECK, uCode[AID_CHECK] | xport_audio); printf("Xport ucode at 0x%x changed from 0x%08x to 0x%08x.\n", AID_CHECK, uCode[AID_CHECK], uCode[AID_CHECK] | xport_audio);#endif } else { /* PS use DVD ucode */ pid[1] = xport_audio | 0x1c0; patch_xport_ucode(PS_BYPASS, uCode[PS_BYPASS] & x07f07fff); printf("Xport ucode at 0x%x changed from 0x%08x to 0x%08x.\n", PS_BYPASS, uCode[PS_BYPASS], uCode[PS_BYPASS] & x07f07fff); } } else { pid[0] = xport_video; pid[1] = xport_audio; } pid[0] = makepid(pid[0], 0, 0, DestVideo); pid[1] = makepid(pid[1], 0, 0, DestAudio); printf("Video cam: 0x%08x. Audio cam 0x%08x\n",pid[0],pid[1]); }#endif load_xport_cam(pid, pidsize); /* xport input mode depends on the xport type and the input xfer mode */ mode = select_xport_mode(xport_type); if (xfer_mode == 5) mode &= ~1; /* TDM */ mvd[xport_input_mode] = mode; /* 3:dvb mode,0x13:alt mode */ mvd[xport_misc] = XPORT_RESET; mvd[xport_interupt_mask] = 0x10L; /* Enable sequence interrupt */ mvd[r_hostctl] = 0x4L; /* host */ mvd[xport_flush_output] = 0xfL; mvd[xport_flush_output] = 0x0L; return(xport_type);}/************************************************************************ Restart xport at the specified address. ************************************************************************/void XPORT_restart_at(int address, int byte_swap){ TDM_expectBreak = 1; /* currCDtime will break; */#if (MPEG1 && MKROM) XPORT_restore_e0_c0(); /* Restore XPORT CAM for safety. */#endif /* Don't know why, but the following two lines are needed. */ mvd[xport_misc] = XPORT_LDMC | XPORT_RESET; (void)mvd[xport_microcode_table + address]; /* dummy access for PC */ mvd[xport_misc] = XPORT_RESET; mvd[xport_pc] = address; mvd[xport_misc] = (byte_swap)? 0x8L : 0x0L; mvd[xport_pc] = 0x80L + address; XPORT_start = 2; /* Tell outside that XPORT has started */}#ifdef XPORT20/************************************************************************ * Restart xport for 2.0 VCD (set begCDtime/endCDtime) * ************************************************************************//* * Change one line of transport microcode. For 2.0 players, we need * to set begCDtime/endCDtime. * * Input: * line: microcode line offset * data: data. The least significant byte goes to the immediate * field. * * Output: * data >> 8 */PRIVATE unsigned int XPORT_UcodeImmd(line, data)int line;unsigned int data;{ unsigned int tmp; /* * Transport microcode table has to be read twice, the first time * it returns garbage. */ reg0 = mvd[xport_microcode_table + line]; tmp = mvd[xport_microcode_table + line] & 0xffffff00; mvd[xport_microcode_table + line] = tmp | (data & 0xff); return (data >> 8);}/* * Change the match_channel ucode line: * either * if (!match(0)) {adv_cmd; goto real_data;} * or * adv_cmd; goto real_data; * * For E1/E2 data, we throw away the data if channel number is 0. For * E0 data, we ignore the channel number. * * Input: * check: 1 for E1/E2 data * 0 for E0 data */PRIVATE void XPORT_adj_match_channel(check)int check;{ unsigned int tmp; /* * Transport microcode table has to be read twice, the first time * it returns garbage. */ reg0 = mvd[xport_microcode_table + XPORT_OFFSET_MATCH_CHANNEL]; /* Ucode with condition field masked off */ tmp = mvd[xport_microcode_table + XPORT_OFFSET_MATCH_CHANNEL] & x07f07fff; if (check) tmp |= 0x48000; /* if (!match(0)) */ mvd[xport_microcode_table + XPORT_OFFSET_MATCH_CHANNEL] = tmp;}/* * This routine is called by 2.0's playSectors (2324), getSectors (2048), * playSectors_step_by_step (2324), and fuzzyPlaySector(2324) * * Following entry points should be used: * XPORT_OFFSET_FUZZY_PLAY: for fuzzyPlaySector * XPORT_OFFSET_PLAY_SECTOR: for playSectors and step_by_step * XPORT_OFFSET_GET_SECTOR: for getSectors * * This code will modify the transport microcode to customize for * begCDtime (if necessary) and endCDtime (always) * * playCDDA should call XPORT_restart_at(XPORT_OFFSET_PLAY_CDDA, 1) * * Input: * entry: entry point * still: For fuzzy/playSectors: resolution of still picture * For getSectors: size of the sector */void XPORT_play20video(entry, still)int entry;int still;{ unsigned int time;#if 0 extern int save_ramcode; /* Microcode may have been changed to do CDDA mono L/R */ if (save_ramcode != -1) { VP_load_ucode(save_ramcode); save_ramcode = -1; }#endif currCDtime = 0; /* Clear it */ /* Load CAM to specify which kind of still picture to match */ mvd[xport_misc] = XPORT_LDPID | XPORT_RESET; /* Load microcode for begCDtime and endCDtime */ mvd[xport_misc] = XPORT_LDMC | XPORT_RESET; time = begCDtime; /* Set begCDtime to be matched */ time = XPORT_UcodeImmd(XPORT_OFFSET_BEG_FF, time); time = XPORT_UcodeImmd(XPORT_OFFSET_BEG_SS, time); time = XPORT_UcodeImmd(XPORT_OFFSET_BEG_MM, time); time = endCDtime; /* Set endCDtime to be matched */ time = XPORT_UcodeImmd(XPORT_OFFSET_END_FF, time); time = XPORT_UcodeImmd(XPORT_OFFSET_END_SS, time); time = XPORT_UcodeImmd(XPORT_OFFSET_END_MM, time); if (entry == XPORT_OFFSET_GET_SECTOR) { int size; /* * Adjust the size of sector. * Assuming 2048+0 <= size <= 2048 + 0xff * * Older getSectors code sets "still" to 0; make sure they are not * affected. */ size = still ? (still - 2048) : 0; (void) XPORT_UcodeImmd(XPORT_OFFSET_LOAD_GETSECTOR_LOW3, size); } else { /* for e1 0r e2 stream, we need to or 0x100 for xport. */ if (still & 0x3) still |= 0x100; mvd[xport_pid_table + XPORT_PID_E1E2] = PID_ID(still) | PID_DEST_VIDEO; /* * Note: if you want to read PID table, you have to read it twice, * the first time it returns junk. */ /* Adjust match_channel ucode */ XPORT_adj_match_channel(still & 0x3); } XPORT_restart_at(entry, 0); if ((entry == XPORT_OFFSET_PLAY_SECTOR) || (entry == XPORT_OFFSET_GET_SECTOR)) { TDM_found_begCDtime = 0; TDM_trigger = 0; XPORT_active = 0; } else XPORT_active = 1; /* Fuzzy play */}/* * Flush out the gateway FIFO relating to transport. This routine is * called when transport is done so all the incoming data will go * to DRAM. */void XPORT_flushGateway(void){ gbl_gate_control |= (flush_xportv | flush_xporta); mvd[gate_control] = gbl_gate_control; risc_sleep_a_bit(600); gbl_gate_control &= ~(flush_xportv | flush_xporta); mvd[gate_control] = gbl_gate_control;}#endif /* XPORT20 */#ifdef XPORT11/* * For 1.1 players, the kind of still picture to be displayed is determined * during run time (i.e. if there is no E2, then display E1.) When this * detection is made, TDM calls this routine to change the XPORT CAM * table. Since E1/E2 is only needed for VCD, we always resume playing * at FUZZY_PLAY's entry point. */void XPORT_loadstill(still)int still;{ /* Load CAM to specify which kind of still picture to match */ mvd[xport_misc] = XPORT_LDPID | XPORT_RESET; mvd[xport_pid_table + XPORT_PID_E1E2] = PID_ID(still) | PID_DEST_VIDEO; XPORT_restart_at(XPORT_OFFSET_FUZZY_PLAY, 0); }#endif /* XPORT11 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -