TVG.c
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:53k
- #include "Config.h" // Global Configuration - do not remove!
- #ifdef TV_GUARDIAN_ENABLE
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "Playcoretvgtvg.h"
- #include "Playcoretvgtvglo.h"
- #include "Playcoretvgtvgcode.h"
- #define TV_GUARDIAN_ENABLE
- #include "Playcoretvgtvgapi.h"
-
- //**********************************************************************
- // RAM global registers
- //**********************************************************************
- #include "Playcoretvgtvgram.c"
- //**********************************************************************
- //**** ROM Constants
- //**********************************************************************
- #include "Playcoretvgtvgdict.c"
- #include "Playcoretvgtvgpar.c"
- //**********************************************************************
- //**** Internal Function Prototypes
- //**********************************************************************
- // Internal TVG Functions
- // BUFF ccbuff routines
- void next_ccbuff_pos( void );
- void next_ccbuff_char( void );
- void cussword_right( void );
- void cussword_left( void );
- // CCUTIL gen purpose cc routines
- uchar chk_if_cmd( void );
- uchar chk_if_letter( void );
- void chk_case( void );
- uchar chk_if_punct( void );
- void chk_plural( void );
- void chk_cc_char( void );
- // CUSS cussword routines
- void chkforcuss( void );
- uchar find_word( void );
- void find_word_nextltr( void );
- void chk_grammar( void );
- void cussword_watch( void );
- void cussword_len( void );
- // IOUTIL i/o routines
- void send2chars( void );
- void insert2spaces( void );
- void process_cc( void );
- // Simulated EEPROM Dictionary Routines
- void get_ee_char( void );
- void get_ee_char_next( void );
- void get_ee_addr( void );
- // HWUTIL hardware routines
- //**********************************************************************
- //**********************************************************************
- //***
- //*** TVG Specific Functions
- //***
- //**********************************************************************
- //**********************************************************************
- #define CMD_POWER_ON 0
- #define CMD_REINIT 1
- #ifdef DEC14TEST
- FILE *dbug;
- #endif
- void tvg_init( uchar cmd ) {
- uchar i;
-
- // Zero out all TVG memory locations from SIMRAM.H
- tvg_flags=0;
- ee_addr=0;
- dummy=0; dummy2=0;
- io_map=0;
- timer_mute=0; timer_tvg=0;
- counter=0;
- r0=0; r1=0; prev_c1=0; prev_c2=0;
- replace_index=0;
- start_of_word=0; first_char=0; last_char=0;
- words_found=0; word_length=0;
- errors_cc=0;
- cc_buffer_in=0; cc_buffer_out=0; cc_buffer_pos=0;
- for(i=0;i<CC_BUFFER_LEN;i++) cc_buffer[i]=0;
- // Zero out all TVG memory locations from this file
- w=0; fsr=(uchar*)NULL;
- brtemp=0;
- for(i=0;i<CCMAXFIFO;i++) ccfifo[i]=0;
- iccfifo=0;
- occfifo=0;
- /*** INITIALIZE THINGS *****/
- cc_buffer_in=0;
- cc_buffer_out=0;
- cc_buffer_pos=0;
- for(i=0;i<CC_BUFFER_LEN;i++) cc_buffer[i]=0;
- if(cmd==CMD_POWER_ON) {
- tvg_flags |= POWER_ON; // Indicate first time loop for tvg_process()
- #ifdef DEC14TEST
- dbug=fopen("debug.dat","w");
- #endif
- }
- if(cmd==CMD_REINIT) {
- tvg_flags |= TVG_MUTE;
- timer_mute = 2 * 30; // Load mute timer w/2 seconds
- }
- tvg_flags |= FIRST_LOOP; // Indicate first time loop for tvg_process()
- tvg_process_modes();
- /* OTHERS...????? */
- timer_tvg=0; // so proccc() will be called
- return;
- }
- void tvg_process( uchar *ccdata, uchar *ccdata_out, uchar field ) {
- uchar c1,c2;
- uchar i,j;
- tvg_process_modes();
- if(tvg_flags & FORCE_NULLS) { // force nulls, no processing
- ccdata_out[0]=0x80;
- ccdata_out[1]=0x80;
- return;
- }
- if(tvg_flags & POWER_ON) {
- // this is where we would display a long message
- // show_tvg_bug(BUG_TVG_VERSION);
- tvg_flags &= ~POWER_ON;
- }
- if(io_map & TVG_OFF) { // just pass data thru - no processing
- ccdata_out[0]=ccdata[0];
- ccdata_out[1]=ccdata[1];
- return;
- }
- //****************************************************************
- //**** THE MAIN TVG PROCESSING LOOP ****
- //****************************************************************
- if(tvg_flags & FIRST_LOOP) {
- chkforcuss(); // check if next word is a cussword
- goto MAIN_0;
- }
- MAIN_ENTRY:
- tvg_process_timers();
- //Save incoming pair of CC characters
- //formerly get2chars function...
- c1=ccdata[0] & 0x7F;
- c2=ccdata[1] & 0x7F;
- if(ccdata[0] != mkpar[c1]) c1=0x7C; // parity err -> block char TEST - really should be 0x7F
- if(ccdata[1] != mkpar[c2]) c2=0x7C; // parity err -> block char
- fsr=cc_buffer+cc_buffer_in;
- *fsr=c1;
- fsr++;
- *fsr=c2;
- cc_buffer_in += 2;
- cc_buffer_in %= CC_BUFFER_LEN;
- //end get2chars
- MAIN_0:
- if(errors_cc > MAX_CCERRORS ) { /* check if too many cc errors */
- tvg_flags &= ~IN_POPON; //clr
- }
- MAIN_1: /*** SEND/EXTRACT CC DATA (FILL BUFFER UP TO CURRENT POSITION) ***/
- #if 0
- w = cc_buffer_pos - cc_buffer_out;
- if((char)w<0) w+=CC_BUFFER_LEN; /* buffer wrap-around??? */
- if(w<2) { /* else, check next word */
- chkforcuss(); /* check if next word is a cussword */
- goto MAIN_0;
- }
- #endif
- sw = cc_buffer_pos - cc_buffer_out;
- if(sw<0) sw+=CC_BUFFER_LEN; /* buffer wrap-around??? */
- if(sw<2) { /* else, check next word */
- chkforcuss(); /* check if next word is a cussword */
- goto MAIN_0;
- }
- send2chars(); // put oldest 2 CC chars to OSD
- transmit2chars(ccdata_out, field);
- if(tvg_flags & FIRST_LOOP) {
- tvg_flags &= ~FIRST_LOOP;
- goto MAIN_ENTRY;
- }
- }
- void chkforcuss( void ) {
- uchar i,j;
- if(!(tvg_flags & IN_POPON)) { /* are we in a pop-on? */
- next_ccbuff_pos(); /* no, don't search for cuss */
- return;
- }
- counter=CC_BUFFER_LEN - 2;
- fsr = cc_buffer + cc_buffer_pos; /* point to current buffer posn */
- CHKFORCUSS_FS: /* (2) FIND START OF NEXT WORD */
- w=*fsr;
- if(chk_if_cmd()) {
- next_ccbuff_pos(); /* skip whole CC cmd pair */
- next_ccbuff_pos(); /* advance to next buffer posn */
- return;
- }
- CHKFORCUSS_NL: /* next letter */
- chk_case(); /* convert lowercase chars if necessary */
- if(!chk_if_letter()) {
- next_ccbuff_pos(); /* advance to next buffer posn */
- return;
- }
- CHKFORCUSS_SS: /* (3) SAVE START OF WORD POSITION */
- start_of_word = cc_buffer_pos; /* save start of word posn */
- first_char = *fsr; /* save first character, too */
- CHKFORCUSS_FE: /* (4) FIND END OF WORD */
- do {
- w=*fsr; /* char @current posn */
- chk_case();
- if(!chk_if_letter()) goto CHKFORCUSS_SE;
- last_char=*fsr; /* SAVE CHAR AS LAST CHAR OF WORD */
- next_ccbuff_pos();
- } while( --counter > 0 );
- return;
- CHKFORCUSS_SE: /* (5) END OF WORD FOUND */
- // Eliminate this; check for TVG off is done at start of tvg_process
- // if(io_map & TVG_OFF) return; /* return - no need to check */
- ee_addr = 0; /* point to beg section of dict */
- w=first_char;
- if( w<'D') goto CHKFORCUSS_CW;
- ee_addr += 0x010; // 0x010
- if( w<'G') goto CHKFORCUSS_CW;
- ee_addr += 0x010; // 0x020
- if( w<'J') goto CHKFORCUSS_CW;
- ee_addr += 0x010; // 0x030
- if( w<'P') goto CHKFORCUSS_CW;
- ee_addr += 0x010; // 0x040
- if( w<'T') goto CHKFORCUSS_CW;
- ee_addr += 0x010; // 0x050
- CHKFORCUSS_CW: /* (7) CHECK IF WORD IS CUSSWORD */
- get_ee_addr(); //Get offest to start of desired section
- replace_index=0xff;
- #if 0
- if(find_word()) goto CUSSWORDFOUND_RET; /* not a cussword (note neg logic */
- #endif
- j=find_word();
- #if 1
- #ifdef DEC14TEST
- fprintf(dbug,"LOOKING FOR WORD:===============n" );
- fprintf(dbug,"start of word.......> %02xn", start_of_word );
- fprintf(dbug,"first char..........> %cn", first_char );
- fprintf(dbug,"last char...........> %cn", last_char );
- fprintf(dbug,"counter.............> %02xn", counter );
- fprintf(dbug,"words found.........> %02xn", words_found );
- fprintf(dbug,"word length.........> %02xn", word_length );
- fprintf(dbug,"eow_flags...........> %02xn", eow_flags );
- fprintf(dbug,"word_toler..........> %02xn", word_toler );
- fprintf(dbug,"replace_index.......> %02xn", replace_index );
- fprintf(dbug,"tvg_flags...........> %08lxn", tvg_flags );
- fprintf(dbug,"cc_buffer...........>" );
- for(i=0;i<16;i++) fprintf(dbug," %02x", cc_buffer[i] );
- fprintf(dbug,"n " );
- for(i=0;i<16;i++) {
- if(isprint(cc_buffer[i])) fprintf(dbug," %c", cc_buffer[i] );
- else fprintf(dbug," ." );
- }
- fprintf(dbug,"n" );
- #endif
- #endif
- if(tvg_flags & WORD_FOUND) cussword_len();
- if(j) goto CUSSWORDFOUND_RET; /* not a cussword (note neg logic */
- if(tvg_flags & GCHK_FLAG) chk_grammar(); /* check grammar if needed */
- if(!(eow_flags & DICT_WATCHWD)) goto CUSSWORDFOUND; /* process found words */
- // cussword_len();
- goto CUSSWORDFOUND_RET; /* goto process watch word and return */
- CUSSWORDFOUND: /**** CUSS WORD FOUND ****/
- #ifdef DEC14TEST
- fprintf(dbug,"CUSSWORDFOUND:===============n" );
- fprintf(dbug,"start of word.......> %02xn", start_of_word );
- fprintf(dbug,"first char..........> %cn", first_char );
- fprintf(dbug,"last char...........> %cn", last_char );
- fprintf(dbug,"words found.........> %02xn", words_found );
- fprintf(dbug,"word length.........> %02xn", word_length );
- fprintf(dbug,"eow_flags...........> %02xn", eow_flags );
- fprintf(dbug,"word_toler..........> %02xn", word_toler );
- fprintf(dbug,"replace_index.......> %02xn", replace_index );
- fprintf(dbug,"ee_addr.............> %04xn", ee_addr );
- fprintf(dbug,"cc_buffer...........>" );
- for(i=0;i<16;i++) fprintf(dbug," %02x", cc_buffer[i] );
- fprintf(dbug,"n " );
- for(i=0;i<16;i++) {
- if(isprint(cc_buffer[i])) fprintf(dbug," %c", cc_buffer[i] );
- else fprintf(dbug," ." );
- }
- fprintf(dbug,"n" );
- #endif
- mute_audio(); /* mute audio */
- tvg_flags |= CUSSING; /* set flag that cussing detected */
- words_found++; /* incr cussword counter */
- // cussword_len();
- #ifdef DEC14TEST
- fprintf(dbug,"CUSSWORD_LEN:===============n" );
- fprintf(dbug,"start of word.......> %02xn", start_of_word );
- fprintf(dbug,"first char..........> %cn", first_char );
- fprintf(dbug,"last char...........> %cn", last_char );
- fprintf(dbug,"word length.........> %02xn", word_length );
- #endif
- chk_plural(); /* check for plural words */
- #ifdef DEC14TEST
- fprintf(dbug,"CHK_PLURAL:===============n" );
- fprintf(dbug,"start of word.......> %02xn", start_of_word );
- fprintf(dbug,"first char..........> %cn", first_char );
- fprintf(dbug,"last char...........> %cn", last_char );
- fprintf(dbug,"word length.........> %02xn", word_length );
- fprintf(dbug,"n" );
- #endif
- CUSSWORDFOUND_0: /* (4) LOCATE REPLACEMENT WORD */
- ee_addr=0x060; /* offset to replacement table stored here */
- get_ee_addr(); /* Get it */
- get_ee_char(); /* access beg of niceword table */
- dummy=w; /* save first char in dummy */
- w=replace_index & INDEX; /* get offset into nice word table */
- if(w==0) goto CUSSWORDFOUND_2; /* skip locate word if zero index */
- counter=w; /* replacement index -> counter */
- CUSSWORDFOUND_1:
- get_ee_char_next(); /* get next niceword letter -> W */
- if(w!=0) goto CUSSWORDFOUND_1; /* keep looking for end of word */
- counter--;
- if(counter !=0) goto CUSSWORDFOUND_1; /* keep looking for indexed word */
- get_ee_char_next(); /* move to 1st ltr of niceword */
- dummy=w; /* save in dummy */
- CUSSWORDFOUND_2: /* (5) POINT TO CUSSWORD */
- fsr=cc_buffer+start_of_word; /* point start of cussword in buff */
- CUSSWORDFOUND_3: /* (6) REPLACE CUSSWORD W/ NICEWORD */
- *fsr=w; /* replace cuss ltr w/nice ltr */
- next_ccbuff_char(); /* next cussword ltr posn */
- /* NOTE: return value is ignored in original assy code */
- if(w==0) goto CUSSWORDFOUND_3A; /* chk if done replacing */
- get_ee_char_next(); /* get next niceword letter */
- dummy=w;
- CUSSWORDFOUND_3A:
- word_length--;
- if(word_length!=0) goto CUSSWORDFOUND_3; /* keep replacing cuss word */
- if(w==0) goto CUSSWORDFOUND_RET; /* return if niceword compl (NULL) */
- /**** INSERT REST OF NICEWORD ****/
- CUSSWORDFOUND_4: /* (1) START AT IN_POSITION - 1 */
- counter=cc_buffer_in;
- w=cc_buffer_in;
- /* (2) SEND OLDEST 2 CHARS */
- send2chars(); /* SEND NEXT 2 CHARS TO OSD */
- cc_buffer_in=cc_buffer_out;
- ee_addr--; /* dec eeprom addr, read char */
- get_ee_char();
- dummy=w;
- CUSSWORDFOUND_5: /* (4) GET CHAR AT CURRENT POSITION */
- w=1;
- cussword_left(); /* move pointer left one */
- fsr=cc_buffer+counter; /* point to cc buffer in posn */
- w=*fsr; /* get char */
- dummy2=w; /* save it in dummy2 */
- w=2; /* (5) MOVE POINTER + 2 */
- cussword_right(); /* move pointer right by two */
- /* (6) PUT CHAR AT NEW LOCATION */
- fsr=cc_buffer+w; /* point to new location */
- *fsr=dummy2; /* put char in new posn */
- w=2; /* (7) MOVE POINTER - 2 */
- cussword_left(); /* move pointer left two */
- /* (8) CHECK IF ENOUGH CHARS MOVED */
- if(cc_buffer_pos!=counter) /* keep shifting chars until */
- goto CUSSWORDFOUND_5; /* pointer = posn */
- /* (9) INSERT 2 NICEWORD CHARS */
- fsr=cc_buffer+cc_buffer_pos; /* point to where we left off */
- dummy2=2; /* save 2 -> dummy2??? */
- w=dummy; /* restore niceword letter */
- CUSSWORDFOUND_6:
- dummy=w; /* save nice letter */
- *fsr=w; /* put niceword letters at pos */
- next_ccbuff_pos(); /* next cussword letter posn */
- w=1;
- cussword_right(); /* move pointer right 1 */
- get_ee_char_next(); /* get next niceword letter */
- dummy2--;
- if(dummy2!=0) goto CUSSWORDFOUND_6; /* do one more character */
- /* (10) CHECK IF DONE INSERTING */
- if(dummy==0) goto CUSSWORDFOUND_RET; /* done if null */
- dummy=w; /* save nice letter -> dummy */
- if(dummy==0) goto CUSSWORDFOUND_RET; /* done if null */
- goto CUSSWORDFOUND_4; /* else, go do two more chars */
- CUSSWORDFOUND_RET: /**** RETURN FROM CHKFORCUSS ****/
- cussword_watch(); /* process watch words */
- return;
- }
- /******************************************************************************
- ;* FUNCTION: CHK_IF_CMD
- ;* DESC: CHECK IF CURRENT CHAR IS A CC CMD PREFIX
- ;* INPUT: W = CHAR
- ;* OUTPUT: W = INPUT CHAR, C = STATUS (0=NOT A CMD CHAR,1=CMD CHAR)
- */
- uchar chk_if_cmd( void ) {
- if( (w>0x09) && (w<=0x17) ) return 1;
- else return 0;
- }
- /******************************************************************************
- ;* FUNCTION: CHK_IF_LETTER
- ;* DESC: CHECK IF CURRENT CHAR IS A LETTER
- ;* INPUT: W = CHAR
- ;* OUTPUT: W = INPUT CHAR, CARRY = STATUS (0=NOT A LETTER,1=LETTER)
- */
- uchar chk_if_letter( void ) {
- if( (w>='A') && (w<='Z') ) return 1;
- else return 0;
- }
- /******************************************************************************
- ;* FUNCTION: CHK_CASE
- ;* DESC: IF LETTER IS LOWER CASE, CONVERT TO UPPER
- ;* INPUT: FSR = POINTER TO CHAR
- ;* OUTPUT: W = INPUT CHAR (CONVERTED TO UPPER IF NECESSARY)
- */
- void chk_case( void ) {
- w=*fsr;
- if( (w>='a') && (w<='z') ) {
- w -= ('a' - 'A');
- *fsr=w;
- }
- return;
- }
- /******************************************************************************
- ;* FUNCTION: CHK_IF_PUNCT
- ;* DESC: CHECK IF CURRENT CHAR IS NOT ACCEPTABLE PUCTUATION TO
- ;* PRECEDE LETTERS ON A LINE
- ;* INPUT: W = CHAR
- ;* OUTPUT: W = INPUT CHAR, CARRY = STATUS (SET=NOT OK,CLEAR=OK)
- */
- uchar chk_if_punct( void ) {
- if(w==' ') return 1;
- if(w=='!') return 1;
- if(w==''') return 1;
- if(w=='.') return 1;
- if(w==',') return 1;
- if(w=='?') return 1;
- return 0;
- }
- /******************************************************************************
- ;* FUNCTION: FIND_WORD
- ;* DESC: SEARCH FOR WORD IN CUSSWORD DICTIONARY
- ;* OUTPUT: Z = STATUS (1=NOT FOUND,0=FOUND), REPLACE_INDEX
- */
- uchar find_word( void ) {
- tvg_flags &= ~WORD_FOUND;
- FIND_WORD:
- get_ee_char();
- dummy=w;
- tvg_flags &= ~NR_FLAG; /* CLEAR "NON-ROOT CUSS WORD" FLAG */
- FIND_WORD_0: /* (1) POINT TO START OF WORD */
- fsr=cc_buffer+start_of_word;
- counter=0; /* 0 --> CUSS WORD LETTER COUNTER */
- tvg_flags &= ~TEMP_GC; /* CLEAR "GRAMMAR CHECK NEEDED" FLAG */
- tvg_flags |= DUMMY_FLAG; /* ASSUME PLURALS ARE OK */
- FIND_WORD_1: /* (2) GET DICTIONARY LETTER */
- if(dummy==0xff) goto FIND_WORD_DONE; /* if end of table, done searching */
- brtemp=dummy;
- if(brtemp & BIT_EOW) goto FIND_WORD_FOUND; /* WORD FOUND !!! */
- #if 0
- // This section from legacy v1 dictionary code
- if(dummy==0) { /* (3) CHECK IF AT END OF A NON-ROOT */
- tvg_flags |= NR_FLAG; /* SET "NON-ROOT CUSS WORD" FLAG */
- goto FIND_WORD_NC; /* skip to next CC char */
- }
- FIND_WORD_2: /* (4) CHECK IF GRAMMAR CHECK NEEDED */
- if(dummy==1) {
- tvg_flags |= TEMP_GC; /* SET "GRAMMAR CHECK NEEDED" FLAG */
- goto FIND_WORD_NC; /* skip to next CC char */
- }
- FIND_WORD_3: /* (5) CHECK IF PLURALS ARE ALLOWED */
- if(dummy==2) {
- tvg_flags &= ~DUMMY_FLAG; /* DON'T ALLOW TO BE PLURAL */
- goto FIND_WORD_NC; /* skip to next CC char */
- }
- // End of legacy flags section
- #endif
- FIND_WORD_CMP: /* (6) COMPARE CC AND DICT. LETTERS */
- chk_case(); /* conv lowercase chars if necessary */
- w=dummy; /* save dictionary letter in W */
- if((*fsr)<w) {
- goto FIND_WORD_DONE; /* done searching if DictLtr < CCchar */
- }
- if((*fsr)>w) {
- goto FIND_WORD_NEXTWORD; /* else goto next dictionary word */
- }
- /* else... DictLtr==CCchar */
- /* (7) PREPARE FOR NEXT CHAR */
- counter++; /* CUSSWORD LETTER COUNTER ++ */
- next_ccbuff_char(); /* NEXT LETTER OF CC WORD */
- /* NOTE: return value is ignored in original assy code */
- FIND_WORD_NC:
- find_word_nextltr(); /* NEXT DICTIONARY LETTER --> DUMMY */
- goto FIND_WORD_1; /* KEEP COMPARING LETTERS */
- FIND_WORD_NEXTWORD: /**** MOVE TO NEXT DICT. WORD ****/
- find_word_nextltr(); /* NEXT DICTIONARY LETTER --> DUMMY */
- brtemp=dummy;
- if(brtemp & BIT_EOW) { /* end of dictionary word? */
- find_word_nextltr(); /* skip over tolerance*/
- find_word_nextltr(); /* skip over replacement index */
- find_word_nextltr(); /* next dictionary letter --> dummy */
- goto FIND_WORD_0; /* continue searching */
- } else goto FIND_WORD_NEXTWORD; /* keep looking for end of word */
- FIND_WORD_FOUND:
- // dummy is holding EOW flags
- eow_flags=dummy;
- if(eow_flags & DICT_NONROOT) tvg_flags |= NR_FLAG;
- if(eow_flags & DICT_GRCHECK) tvg_flags |= TEMP_GC;
- if(eow_flags & DICT_PLURALS) tvg_flags &= ~DUMMY_FLAG;
- tvg_flags |= WORD_FOUND;
- // read cuss word tolerance
- get_ee_char();
- word_toler = w;
- // read replacement word index
- get_ee_char();
- replace_index = w;
- /**** WORD FOUND ****/
- /* (1) CHECK IF AT END OF A NON-ROOT */
- if(!(tvg_flags & NR_FLAG)) goto FIND_WORD_FOUND_0; /* Cuss Word Found */
- /* else, Non-Root Cuss Word found */
- tvg_flags &= ~NR_FLAG; /* CLEAR "NON-ROOT CUSS WORD" FLAG */
- w=*fsr; /* next cc char -> w */
- if(chk_if_letter()) {
- replace_index=0xff; /* "no words found" -> replace_index */
- goto FIND_WORD_FOUND_1; /*(skip replacement word assignment)*/
- }
- FIND_WORD_FOUND_0:
- // This isn't needed any more with version 2 dictionary
- // replace_index=dummy; /* (2) store replacement index */
- FIND_WORD_FOUND_1:
- next_ccbuff_char(); /* (3) next letter of CC word */
- /* (4) continue searching */
- find_word_nextltr(); /* next dictionary letter -> dummy */
- word_length=counter; /* (5) save cussword length */
- /* (6) save plural and grammar flags */
- if(tvg_flags & DUMMY_FLAG) tvg_flags |= PLURAL;
- else tvg_flags &= ~PLURAL; /* save plural flag */
- if(tvg_flags & TEMP_GC) tvg_flags |= GCHK_FLAG;
- else tvg_flags &= ~GCHK_FLAG; /* save grammar chk flag */
- goto FIND_WORD_0; /* continue looking */
- FIND_WORD_DONE: /**** DONE SEARCHING ****/
- if(eow_flags & DICT_WATCHWD) /* indicate WORD FOUND... */
- goto FIND_WORD_DONE_0; /* ...if word isn't watch word */
- // Blocking Logic
- // WAS:
- // if(io_map & TVG_STRICT)
- // goto FIND_WORD_DONE_0; /* ...if in STRICT mode */
- // if(!(replace_index & BIT_TLRNT))
- // goto FIND_WORD_DONE_0; /* ...if not TOLERANT mode */
- if( word_toler & iomap2 )
- goto FIND_WORD_DONE_0; /* check for blocking or not... */
-
- return 1; /* return 1 = no cussword found */
- FIND_WORD_DONE_0:
- w=replace_index+1; /* check replacement index */
- if(w==0) return 1; /* return 1 if no cussword found */
- else return 0; /* return 0 if cussword found */
- }
- void find_word_nextltr( void ) {
- get_ee_char_next(); /* NEXT DICTIONARY LETTER --> DUMMY */
- dummy=w;
- return;
- }
- /******************************************************************************
- ;* FUNCTION: GET_EE_CHAR
- ;* DESC: READ CHAR FROM EEPROM
- ;* INPUT: OUT_BUFFER, OUT_BUFFER2 = EEPROM ADDRESS TO READ, (L,H)
- ** ^^^^^^^^^^ ^^^^^^^^^^^
- ** really: ee_add_lo ee_add_hi ?????
- ;* OUTPUT: W = BYTE READ
- ** also: IN_BUFFER holds the character read
- ;* NOTE: SEQUENTIAL READS POSSIBLE BY CALLING GET_EE_CHAR_NEXT
- ;* BUT MUST BE DONE WHILE SPI_SEL HELD LOW
- * In this C-Language simulation, the EEPROM data is in a large 2K array - no
- * need to manipulate clock and data lines to fetch a data byte - just index
- * into the array. NOTE: Because of this, there is no difference between the
- * functions get_ee_char and get_ee_char_next.
- */
- void get_ee_char( void ) {
- w=tvg_dict[ee_addr]; /* fetch word, store into */
- ee_addr++; /* increment address */
- return;
- }
- void get_ee_char_next( void ) {
- w=tvg_dict[ee_addr]; /* fetch word, store into */
- ee_addr++; /* increment address */
- return;
- }
- // This function for version 2 dictionary, fetches two-byte address from
- // the indicated offset, and re-loads the ee_addr variable.
- // Assume that section offsets are stored in the little-endian Intel
- // format. This is safe assumption on any machine, because we dictate
- // how dictionary is generated and stored.
- void get_ee_addr( void ) {
- w=tvg_dict[ee_addr];
- ee_addr++;
- dummy=tvg_dict[ee_addr];
- ee_addr = w + (dummy << 8);
- }
- /******************************************************************************
- ;* FUNCTION: CHK_GRAMMAR
- ;* DESC: CHECK SPECIAL WORD/GRAMMAR SITUATIONS
- ;* NOTES: BASIC RULE: DID WATCH WORD PRECEDE WORD?
- ;* YES -->
- */
- void chk_grammar( void ) {
- if(tvg_flags & DW_0) return; /* was prev word a watch word? */
- if(tvg_flags & DW_1) return; /* was two words ago a watch word? */
- replace_index=0xff; /* return "no words found" */
- return;
- }
- /* FUNCTION: CUSSWORDLEN
- * DESC: GET LENGTH OF WORD/PHRASE
- */
- void cussword_len( void ) {
- uchar i;
- counter=word_length;
- cc_buffer_pos=start_of_word;
- fsr=cc_buffer+cc_buffer_pos; /* point to start of word */
- CUSSWORD_LEN_0:
- do {
- next_ccbuff_pos(); /* next buffer posn */
- } while( --counter > 0 );
- CUSSWORD_LEN_1: /* advance over any add'l letters */
- chk_case(); /* CONVERT LOWERCASE CHARS IF NECESSARY */
- last_char=w; /* save char -> last char */
- if(!chk_if_letter()) return; /* return w/len if not letter */
- // last_char=w; /* save char -> last char */
- word_length++; /* incr word lenght */
- next_ccbuff_pos(); /* next buffer position */
- goto CUSSWORD_LEN_1;
- }
- /******************************************************************************
- ;* FUNCTION: CHK_PLURAL
- ;* DESC: CHECK FOR PLURAL WORDS
- */
- void chk_plural( void ) {
- if(!(tvg_flags & PLURAL)) return;
- if(last_char=='S') word_length--; /* adjust word length if plural */
- return;
- }
- /******************************************************************************
- ;* FUNCTION: NEXT_CCBUFF_POS
- ;* DESC: MOVE TO THE NEXT CC_BUFFER POSITION
- ;* OUTPUTS: CC_BUFFER_POS, FSR
- */
- void next_ccbuff_pos( void ) {
- cc_buffer_pos++; /* increment buffer pointer */
- cc_buffer_pos %= CC_BUFFER_LEN; /* handle buffer rollover */
- fsr=cc_buffer + cc_buffer_pos;
- }
- /******************************************************************************
- ;* FUNCTION: NEXT_CCBUFF_CHAR
- ;* DESC: MOVE TO THE NEXT CC_BUFFER CHAR
- ;* OUTPUT: ZERO FLAG: 0=CHARS LEFT TO CHECK,1=NO MORE CHARS
- ;*
- * NOTE: Return value appears to be ignored everywhere, so it has been omitted
- */
- void next_ccbuff_char( void ) {
- uchar zeroflag;
- NEXT_CCBUFF_CHAR:
- zeroflag=0;
- fsr++;
- if( (fsr-cc_buffer) >= CC_BUFFER_LEN) {
- fsr=cc_buffer;
- zeroflag=1;
- }
- return;
- }
- void cussword_right( void ) {
- CUSSWORD_RIGHT: /**** MOVE BUFFER POINTER RIGHT ****/
- /* (INPUT: W = # POSITIONS TO MOVE) */
- /* (OUTPUT: W = NEW POSITION) */
- counter += w; /* incr counter */
- counter%=CC_BUFFER_LEN; /* handle rollover */
- w=counter;
- return;
- }
- void cussword_left( void ) {
- CUSSWORD_LEFT: /**** MOVE BUFFER POINTER LEFT ****/
- /* (INPUT: W = # POSITIONS TO MOVE) */
- /* (OUTPUT: W = NEW POSITION) */
- #if 0
- counter -= w; /* decr counter */
- if((char)counter<0) counter += CC_BUFFER_LEN; /* adj for past start of buffer */
- w=counter;
- #endif
- scounter = (char)counter - w; /* decr counter */
- if(scounter<0) scounter += CC_BUFFER_LEN; /* adj for past start of buffer */
- w=(uchar)scounter;
- counter=w;
- return;
- }
- void cussword_watch( void ) {
- CUSSWORD_WATCH: /**** PROCESS WATCH WORDS IF ANY ****/
- if(tvg_flags & DW_0) tvg_flags |= DW_1;
- else tvg_flags &= ~DW_1; /* shift last word to 2-words ago flag */
- tvg_flags &= ~DW_0; /* assume new word isn't a D/W watch word */
- if(replace_index==0xff) return; /* return if no replacement word */
- if(!(eow_flags & DICT_WATCHWD)) return; /* return if not watch word */
- if(!(eow_flags & DICT_USAGEWW)) return; /* return if not D/W watch word */
- tvg_flags |= DW_0; /* flag that new word is D/W watch */
- return;
- }
- /******************************************************************************
- ;* FUNCTION: SEND2CHARS
- ;* DESC: SEND OLDEST 2 CLOSED CAPTION CHARS TO OSD
- ;
- */
- // For DVD Project, we are going to implement a FIFO buffer into which the
- // character pairs are placed. They will ordinarily be immediately
- // removed from the buffer for transmission. In the case of a substitute
- // niceword which is longer than the cussword, this buffer will be filled
- // briefly with more than one pair of characters.
- void send2chars( void ) {
- // if we are "marking time", i.e., sending a pair of NULLs, and there
- // are already some character pairs in the transmit fifo, dont bother
- // to send the NULLs.
-
- fsr=cc_buffer + cc_buffer_out;
- if( (fsr[0]==0) && (fsr[1]==0) && (iccfifo!=occfifo) ) {
- cc_buffer_out += 2;
- cc_buffer_out %= CC_BUFFER_LEN;
- } else {
- r0=fsr[0];
- r1=fsr[1];
- if(timer_tvg==0) process_cc();
- ccfifo[iccfifo++]=fsr[0];
- ccfifo[iccfifo++]=fsr[1];
- iccfifo %= CCMAXFIFO; //FIFO even size, can only rollover here
- cc_buffer_out += 2;
- cc_buffer_out %= CC_BUFFER_LEN;
- }
- return;
- }
- // this routine used to insert two spaces into the outgoing
- // FIFO. Doesn't adjust CC_BUFFER pointers
- void insert2spaces( void ) {
- ccfifo[iccfifo++]=0x11; // transparent space
- ccfifo[iccfifo++]=0x39;
- iccfifo %= CCMAXFIFO; //FIFO even size, can only rollover here
- ccfifo[iccfifo++]=0x11; // transparent space
- ccfifo[iccfifo++]=0x39;
- iccfifo %= CCMAXFIFO; //FIFO even size, can only rollover here
- return;
- }
- // for DVD implementation, we only call PROCCC() in order to enable and
- // disable various mode flags, which will be set/cleared depending on
- // the control codes in the CC data stream. In the stand-alone TVG unit,
- // this function also sent commands to the OSD chip.
- /******************************************************************************
- ;* FUNCTION: PROCESS_CC
- ;* DESC: TRANSLATE CLOSED CAPTION DATA AND DISPLAY VIA OSD
- ;* INPUT: R0,R1 : CC CHAR PAIR
- ;*/
- void process_cc( void ) {
- PROCESS_CC:
- // (1) CHECK IF IN POP-ON STYLE CC
- // BRANCH IF CC MODE IS NOT ACTIVE
- // ELSE, PROCESS CC CHARS
- if(tvg_flags & CC_ACTIVE) goto PROCESS_CC_0;
- // (2) WAIT FOR POP-ON CMD
- // CHECK FOR MISC PAC CMD
- // BRANCH IF MISC PAC CMD FOUND
- // ELSE, NOTHING TO DO -- RETURN
- if(r0!=CCCMD_MISC) goto PROCESS_CC_RET;
- else goto PROCESS_CC_MISC; // GOTO PROCESS PAC COMMAND
- PROCESS_CC_0:
- if(r0<0x10) goto PROCESS_CC_CHAR; // (4) CHECK IF CC CHARS ARE CTRL CODES
- if(r0>0x17) goto PROCESS_CC_CHAR; // 0x10 <= c1 <=0x17
- if((prev_c1==r0)&&(prev_c2==r1)) // (5) CHECK FOR REDUNDANT CTRL CODES
- goto PROCESS_CC_RET; // ELSE, SKIP REDUNDANT CTRL CODES
- PROCESS_CC_1: // (6) CHECK FOR PAC CODES
- if(r1<0x40) goto PROCESS_CC_CMDS; // ELSE, PROBABLY MISC CTRL CODE
- // (7) "NO WIERD CHARS TILL 1ST LETTER"
- tvg_flags |= NO_LETTERS; // FLAG TO SEND NOTHING TILL 1ST LETTER
- tvg_flags |= IN_POPON; // (8) DO IMPLIED POP-ON STUFF
- // FLAG THAT WE RE IN A POP-ON CC
- errors_cc=0; // RESET CC ERRORS COUNTER
- // Old TVG code actually processed these codes, to determine what had
- // to be sent to the OSD chip for proper formatting of the text -
- // things like indention, italics, underline, etc. In the DVD appl,
- // we only need to note the occurence of certain key control codes
- // so we can go into/leave TVG operation as a function of POPUP
- // closed captioning mode. Further simplification would be possible
- // if we assumed that only POPUP style CC would be found on a DVD.
- // (9) SET OSD ROW
- // PAC command, row obtained from it
- // ANDLW 0FH ;MASK FOR LOWER BYTE
- // MOVWF TABLE_INDEX ;W --> TABLE_INDEX
- // CALL CC_ROW ;RETREIVE BASE ROW FROM (PAC:1 LOW NIBBLE)
- // BTFSC R1,5 ;BRANCH IF BIT 5 OF PAC:2 IS NOT SET
- // ADDLW 1 ; ELSE, ROW ++
- // CALL PUT_TO_OSD
- // ;(10) CHECK TO SET UNDERLINE MODE
- // BTFSC R1,0 ;BRANCH IF BIT 0 OF PAC:2 IS NOT SET
- // CALL PROCESS_CC_UNDLN ; ELSE, GOTO UNDERLINE
- // Note: Original code CALLed UNDERLINE function - since it was
- // only invoked from one place, it has been moved to here and simply
- // enclosed in an IF block. But since no action associated with the
- // DVD player takes place, the whole thing is commented out.
- //
- // (10) CHECK TO SET UNDERLINE MODE
- // if(r1 & 0x01) {
- PROCESS_CC_UNDLN: // *** SET OSD UNDERLINE ***
- // MOVLW OSDCMD_WRCHR ;OSD WRITE CHARACTER MODE
- // CALL PUT_TO_OSD
- // MOVLW OSDCHAR_UNDLN ;OSD SET UNDERLINE MODE
- // CALL PUT_TO_OSD
- // RETURN ;RETURN
- // }
- // ;(11) CHECK TO INDENT CURSOR
- // BTFSC R1,4 ;BRANCH IF BIT 4 OF PAC:2 IS NOT SET
- // GOTO PROCESS_CC_INDENT ; ELSE, GOTO INDENT
- if(r1 & 0x10) goto PROCESS_CC_INDENT;
- // ;(12) CHECK TO SET ITALICS MODE
- // ; (INTALICS PAC2 = 4EH OR 6EH)
- // MOVF R1,W ;2ND CC CHAR --> W
- // ANDLW 11011110B ;MASK FOR BITS 7,6,4,3,2,1
- // SUBLW CCCMD_ITALIC ;CHECK IF PAC:2 = ITALICS
- // BTFSS STATUS,Z ;BRANCH IF PAC:2 = ITALICS
- // GOTO PROCESS_CC_RET ; ELSE, NOTHING MORE TO DO
- if( (r1 & 0xde) != CCCMD_ITALIC )
- goto PROCESS_CC_RET;
- PROCESS_CC_ITALICS: // (13) SET OSD ITALICS
- // MOVLW OSDCMD_WRCHR ;OSD WRITE CHARACTER MODE
- // CALL PUT_TO_OSD
- // MOVF R1,W ;2ND CC CHAR --> W
- // ANDLW 0FH ;MASK FOR LOWER 4 BITS
- // CALL PUT_TO_OSD ;ITALICS OR UNDRLN+ITALICS --> OSD
- // GOTO PROCESS_CC_RET ;RETURN TO TOP OF PROCESS_CC LOOP
- goto PROCESS_CC_RET;
- PROCESS_CC_CHAR: // *** SEND CC CHAR TO OSD ***
- // BRANCH IF WITHIN A POP-ON CC
- // ELSE, DON T ALLOW ANY OUTPUT
- //
- if(!(tvg_flags & IN_POPON)) goto PROCESS_CC_RET;
- //ACTUALLY SEND CHAR OUT HERE
- // Check need to insert extra spaces
- #ifdef INDADJ
- if(r0 || r1) { // only check if not pair of nulls
- if(tvg_flags & INDENT_ADJ) {
- insert2spaces();
- tvg_flags &= ~INDENT_ADJ;
- }
- }
- #endif
- if(r0) {
- w=r0;
- chk_cc_char();
- if(w!=dummy) {
- r0=dummy;
- fsr[0]=dummy;
- }
- }
- if(r1) {
- w=r1;
- chk_cc_char();
- if(w!=dummy) {
- r1=dummy;
- fsr[1]=dummy;
- }
- }
- goto PROCESS_CC_RET; // RETURN TO TOP OF PROCESS_CC LOOP
- // Here again were many special sections in the original TVG code that
- // allowed the software to control the formatting of the OSD - not needed
- // for the DVD program, but for some mode control commands.
- //
- PROCESS_CC_INDENT: // *** INDENT CURSOR ***
- // ;(CODE REWORK - 2/28/98 JMW)
- // MOVLW OSDCMD_SETCOL ;OSD SET COLUMN MODE
- // CALL PUT_TO_OSD
- // RLF R1,W ;MULTIPLY PAC:2 BY 2 --> W
- // ANDLW 1CH ;MASK FOR FOR VALID BITS OF W
- // ADDLW 1 ;ADD IN LEADING SPACE FOR COLUMN 0
- // CALL PUT_TO_OSD ;SEND COLUMN TO OSD
- // GOTO PROCESS_CC_RET ;RETURN TO TOP OF PROCESS_CC LOOP
- #ifdef INDADJ
- tvg_flags &= ~INDENT_ADJ;
- if((r1 & 0x0E)==0) goto PROCESS_CC_RET; // do not process if indent 0
- tvg_flags |= INDENT_ADJ;
- fsr[1] = r1 - 2; // Adjust indent to be one stop back
- #endif
- // For Zoran/Sanyo Jan 2002 Release, only adjust indent back by 1 tab
- // stop (4 spaces). Memory problem associated with subsequent insertion
- // of two transparent spaces.
- if((r1 & 0x0E)==0) goto PROCESS_CC_RET; // do not process if indent 0
- fsr[1] = r1 - 2; // Adjust indent to be one stop back
- goto PROCESS_CC_RET; // RETURN TO TOP OF PROCESS_CC LOOP
- PROCESS_CC_CMDS: // *** PROCESS MISC CTRL CODES ***
- // MOVF R0,W ;1ST CC CHAR --> W
- // SUBLW 017H ;CHECK FOR TAB OFFSET CODE
- // BTFSS STATUS,Z ;BRANCH IF TAB OFFSET CODE
- // GOTO PROCESS_CC_CMDS_1 ; ELSE, CHECK FOR OTHER CODES
- if(r0!=0x17) goto PROCESS_CC_CMDS_1;
- // ;< PROCESS TABS >
- // MOVLW 020H ;20H --> W
- // SUBWF R1,ITSELF ;PAC:2 - 20H --> R1
- // BTFSC STATUS,Z ;BRANCH IF #TABS != 0
- // GOTO PROCESS_CC_RET ; ELSE, SKIP BECAUSE INVALID
- // BTFSS STATUS,C ;BRANCH IF #TABS > 0
- // GOTO PROCESS_CC_RET ; ELSE, SKIP BECAUSE INVALID
- if( r1 <= 0x20 ) goto PROCESS_CC_RET;
- PROCESS_CC_CMDS_0:
- // MOVLW OSDCMD_WRCHR // OSD WRITE CHARACTER MODE
- // CALL PUT_TO_OSD
- // MOVLW 0B8H ;OSD TRANSPARENT SPACE --> W
- // CALL PUT_TO_OSD
- // DECFSZ R1,ITSELF ;TABS --, BRANCH IF DONE
- // GOTO PROCESS_CC_CMDS_0 ; ELSE, KEEP TABBING
- // GOTO PROCESS_CC_RET ;RETURN TO TOP OF PROCESS_CC LOOP
- goto PROCESS_CC_RET;
- PROCESS_CC_CMDS_1: // CHECK FOR OTHER CTRL CODES
- // MOVF R0,W ;1ST CC CHAR --> W
- // SUBLW 014H ;CHECK FOR MISC CTRL CODE
- // BTFSC STATUS,Z ;BRANCH IF NOT MISC CTRL CODE
- // GOTO PROCESS_CC_MISC ; ELSE, PROCESS MISC CTRL CODE
- if(r0==0x14) goto PROCESS_CC_MISC;
- // ;*** CHECK FOR SPECIAL CHARACTERS ***
- // ; ** AND MID-ROW CODES **
- // MOVF R0,W ;1ST CC CHAR --> W
- // SUBLW 011H ;CHECK FOR SPECIAL CHARS/MID-ROW CODES
- // BTFSS STATUS,Z ;BRANCH IF SPECIAL CHAR OR MID-ROW...
- // GOTO PROCESS_CC_RET ; ELSE, CODE UNRECOGNIZED - SKIP IT
- if(r0!=0x11) goto PROCESS_CC_RET;
- // ;(1) CHECK IF TRANSPARENT SPACE CODE
- // MOVF R1,W ;2ND CC CHAR --> W
- // SUBLW 039H ;CHECK FOR TRANSPARENT SPACE CHAR
- // BTFSS STATUS,Z ;BRANCH IF TRANSPARENT SPACE CHAR
- // GOTO PROCESS_CC_CMDS_2 ; ELSE, CHECK IF SPECIAL CHAR
- if(r1!=0x39) goto PROCESS_CC_CMDS_2;
- // MOVLW 1 ;1 --> R1 (1 TRANS. SPACE)
- // MOVWF R1
- // GOTO PROCESS_CC_CMDS_0 ;SEND ONE TRANSPARENT CHAR
- goto PROCESS_CC_CMDS_0;
- PROCESS_CC_CMDS_2: // (2) CHECK IF SPECIAL CHAR
- // MOVLW 30H ;30H --> W
- // SUBWF R1,W ;2ND CC CHAR - 30H --> W
- // BTFSS STATUS,C ;BRANCH IF SPECIAL CHAR
- // GOTO PROCESS_CC_ITALICS ; ELSE, ASSUME MID-ROW CODE (ITALICS)
- if(r1!=0x30) goto PROCESS_CC_ITALICS;
- // ;(3) PROCESS SPECIAL CHARACTERS
- // MOVLW OSDCMD_WRCHR ;OSD WRITE CHARACTER MODE
- // CALL PUT_TO_OSD
- // MOVF R1,W ;2ND CC CHAR --> W
- // ANDLW 0FH ;MASK FOR LOWER NIBBLE OF W
- // ADDLW 10H ;W += 20H (CHAR MUST BE: >20H,<2FH)
- // CALL PUT_TO_OSD ;SPECIAL CHAR --> OSD
- // GOTO PROCESS_CC_RET ;NEXT CHARS
- goto PROCESS_CC_RET;
- PROCESS_CC_MISC: // *** PROCESS MISC CTRL CODES ***
- // MOVLW CCCMD_POPON ;CHECK IF 2ND CC CHAR >= POPON CMD
- // SUBWF R1,W ;2ND CC CHAR - POPON --> W
- // BTFSS STATUS,C ;BRANCH IF CC CHAR >= POPON CMD
- // GOTO PROCESS_CC_RET ; ELSE, DON'T RECOGNIZE CMD, DON'T USE
- if(r1 < CCCMD_POPON) goto PROCESS_CC_RET;
- // MOVF R1,W ;2ND CC CHAR --> W
- // SUBLW CCCMD_EOC ;CHECK IF 2ND CC CHAR <= POPOFF CMD
- // BTFSS STATUS,C ;BRANCH IF CC CHAR <= POPOFF CMD
- // GOTO PROCESS_CC_RET ; ELSE, DON'T RECOGNIZE CMD, DON'T USE
- // GOTO PROCESS_CC_JUMP ;GO PROCESS CONTROL CHARACTER VIA
- // ;A GOTO TABLE
- // ;NOTE:
- if(r1 <= CCCMD_EOC) goto PROCESS_CC_JUMP;
- goto PROCESS_CC_RET;
- PROCESS_CC_POPON: // *** PROCESS "POPON" MODE ***
- tvg_flags &= ~CMD_SUBST; // Always clear Command Substitute flag upon
- // receipt of POPON command
- #ifdef INDADJ
- tvg_flags &= ~INDENT_ADJ; // Always clear Indent Adjust flag upon
- // receipt of POPON command
- #endif
- // ;(1) CHECK IF POP-ON CC STYLE ACTIVE
- // BTFSC PRG_STATUS_2,CC_ACTIVE ;BRANCH IF POP-ON NOT ALREADY ACTIVE
- // GOTO PROCESS_CC_POPON_0 ; ELSE, GOTO RETURN
- if(tvg_flags & CC_ACTIVE) goto PROCESS_CC_POPON_0;
- // BSF PRG_STATUS_2,CC_ACTIVE ;(2) FLAG THAT POP-ON STYLE ACTIVE
- tvg_flags |= CC_ACTIVE;
- // ;(3) DISPLAY "TVG"
- // MOVLW TVG-VER ;LOCATION OF "TVG" --> W
- // CALL SHOW_TVG_BUG ;DISPLAY "TVG"
- show_tvg_bug(BUG_TVG);
- // CALL CHECK_TO_UNMUTE ;(4) CHECK TO UNMUTE AUDIO
- check_to_unmute();
- PROCESS_CC_POPON_0:
- // BSF PRG_STATUS_5,IN_POPON ;(5) FLAG THAT WE RE IN A POP-ON CC
- tvg_flags |= IN_POPON;
- // CLRF ERRORS_CC ;(6) RESET CC ERRORS COUNTER
- errors_cc=0;
- // GOTO PROCESS_CC_RET ;RETURN
- goto PROCESS_CC_RET;
- PROCESS_CC_RDC: // *** PROCESS PAINT-ON CAPTIONS ***
- // ** RDC --> PAINT-ON COMMAND **
- PROCESS_CC_RU2: // *** SEND "RU2" COMMAND TO OSD ***
- PROCESS_CC_RU3: // *** SEND "RU3" COMMAND TO OSD ***
- PROCESS_CC_RU4: // *** SEND "RU4" COMMAND TO OSD ***
- PROCESS_CC_ROLLUP: // *** PROCESS ROLLUP CAPTIONS ***
- // BCF PRG_STATUS_5,IN_POPON ;(1) FLAG "NOT IN A POP-ON CC"
- // MOVLW OSDCMD_OEDM ;(2) ERASE DISPLAYED MEMORY
- // CALL PUT_TO_OSD
- tvg_flags &= ~IN_POPON;
- // ;(3) CHECK IS CHANGING FROM POP-ON
- // BTFSC PRG_STATUS_2,CC_ACTIVE ;BRANCH IF NOT IN POP-ON STYLE CC
- // GOTO PROCESS_CC_ROLLUP_0 ; ELSE, SHOW "NO TVG"
- if(tvg_flags & CC_ACTIVE) goto PROCESS_CC_ROLLUP_0;
- // ;(4) CHECK IF ALREADY KNOW "NO TVG"
- // BTFSC PRG_STATUS_4,TVG_STATUS ;BRANCH IF TVG STATUS IS UNKNOWN
- // GOTO PROCESS_CC_ROLLUP_RET ; ELSE, GOTO RETURN
- if(tvg_flags & TVG_STATUS) goto PROCESS_CC_ROLLUP_RET;
- PROCESS_CC_ROLLUP_0: // (5) DISPLAY "NO TVG"
- // MOVLW NOTVG-VER ;LOCATION OF "NO TVG" --> W
- // CALL SHOW_TVG_BUG ;DISPLAY "NO TVG"
- show_tvg_bug(BUG_NOTVG);
- PROCESS_CC_ROLLUP_RET:
- // BCF PRG_STATUS_2,CC_ACTIVE ;(6) DISABLE POP-ON CAPTIONS
- // CALL CHECK_TO_UNMUTE ;(7) CHECK TO UNMUTE AUDIO
- // GOTO PROCESS_CC_RET ;(8) GOTO RETURN
- tvg_flags &= ~CC_ACTIVE;
- check_to_unmute();
- goto PROCESS_CC_RET;
- PROCESS_CC_EDM: // *** SEND "EDM" COMMAND TO OSD ***
- // BTFSS PRG_STATUS_2,CUSSING ;BRANCH IF CUSSING DETECTED
- // CALL CHECK_TO_UNMUTE ;CHECK TO UNMUTE AUDIO
- // MOVLW OSDCMD_OEDM ;ERASE DISPLAYED MEMORY
- // CALL PUT_TO_OSD
- // GOTO PROCESS_CC_RET ;GOTO RETURN
- if(!(tvg_flags & CUSSING)) check_to_unmute();
- goto PROCESS_CC_RET;
- PROCESS_CC_CR: // *** SEND "CR" COMMAND TO OSD ***
- // MOVLW OSDCMD_CR ;SEND CARRIAGE RETURN TO OSD
- // CALL PUT_TO_OSD
- // GOTO PROCESS_CC_RET ;GOTO RETURN
- goto PROCESS_CC_RET;
- PROCESS_CC_ENM: // *** SEND "ENM" COMMAND TO OSD ***
- // MOVLW OSDCMD_OENM ;ERASE NON-DISPLAYED MEMORY
- // CALL PUT_TO_OSD
- // GOTO PROCESS_CC_RET ;GOTO RETURN
- goto PROCESS_CC_RET;
- PROCESS_CC_POPOFF: // *** SEND "POPOFF" COMMAND TO OSD ***
- // aaa=10; while(aaa) VCX_service();
- // BTFSS PRG_STATUS_2,CC_ACTIVE ;(1) BRANCH IF POP-ON STYLE ACTIVE
- // GOTO PROCESS_CC_POPON ; ELSE, PROCESS "IMPLIED POPON"
- #ifdef INDADJ
- tvg_flags &= ~INDENT_ADJ; // Always clear Indent Adjust flag upon
- // receipt of POPOFF command
- #endif
-
- if(!(tvg_flags & CC_ACTIVE)) goto PROCESS_CC_POPON;
- if(tvg_flags & CMD_SUBST) {
- fsr[0]=CCCMD_MISC; // replace POPOFF with Erase
- fsr[1]=CCCMD_ENM; // non-displayed memory command
- tvg_flags &= ~CMD_SUBST;
- }
- // ;(2) CHECK IF WITHIN A POP-ON CC
- // BTFSS PRG_STATUS_5,IN_POPON ;BRANCH IF WITHIN A POP-ON CC
- // GOTO PROCESS_CC_RET ; ELSE, GOTO RETURN (MAY BE REDUNDANT)
- if(!(tvg_flags & IN_POPON)) goto PROCESS_CC_RET;
- // GOTO CLOSE_POPON ;(3) CHECK TO END POP-ON CC
- goto CLOSE_POPON;
- PROCESS_CC_POPOFF_0:
- // BCF PRG_STATUS_5,IN_POPON ;FLAG THAT WE RE NOT IN A POP-ON CC
- // MOVLW OSDCMD_FLIP ;EXIT OSD POPSET MODE (FLIP TO OSD)
- // CALL PUT_TO_OSD
- // GOTO PROCESS_CC_RET ;GOTO RETURN
- tvg_flags &= ~IN_POPON;
- goto PROCESS_CC_RET;
- PROCESS_CC_BKSP: // *** SEND "BKSP" COMMAND TO OSD ***
- PROCESS_CC_DER: // *** SEND "DER" COMMAND TO OSD ***
- PROCESS_CC_FON: // *** SEND "FON" COMMAND TO OSD ***
- PROCESS_CC_TR: // *** SEND "TR" COMMAND TO OSD ***
- PROCESS_CC_RTD: // *** SEND "RTD" COMMAND TO OSD ***
- // GOTO PROCESS_CC_RET ;NOT IMPLEMENTED FOR NOW
- goto PROCESS_CC_RET;
- PROCESS_CC_RET: // *** RETURN FROM PROCESS_CC ***
- // MOVF R0,W ;SAVE LAST TWO CC CHARS
- // MOVWF PREV_C1
- // MOVF R1,W
- // MOVWF PREV_C2
- prev_c1=fsr[0]; // use fsr[] so that we will properly replace
- prev_c2=fsr[1]; // the two sequential POPOFF commmands in CC-CUSS mode
- // RETURN
- return;
- //******************************************************************************
- //* FUNCTION: CLOSE_POPON
- //* DESC: CLOSE POP-ON CAPTIONS INCLUDING:
- //* 1) CHECK TO UNMUTE AUDIO BASED ON MUTE TIMER
- //* 2) CHECK TO ERASE NON-DISPLAYED MEMORY IF CAPTIONS NOT
- //* TO BE DISPLAYED (INCLUDING TOO MANY CC ERRORS)
- CLOSE_POPON:
- // aaa=11; while(aaa) VCX_service();
- //*** IF TVG CC IS OFF, DON'T CC ***
- // BTFSC PRG_STATUS_1,TVG_CAPS ;BRANCH IF TVG CAPS SHOULD BE "OFF"
- // GOTO CLOSE_POPON_0 ; ELSE, NO TVG CAPTIONS
- if(tvg_flags & TVG_CAPS) goto CLOSE_POPON_0;
- fsr[0]=CCCMD_MISC; // replace POPOFF with Erase
- fsr[1]=CCCMD_ENM; // non-displayed memory command
- tvg_flags |= CMD_SUBST;
- // MOVLW OSDCMD_OENM ;ERASE NON-DISPLAYED MEMORY
- // CALL PUT_TO_OSD
- CLOSE_POPON_0:
- // BTFSC PRG_STATUS_2,CUSSING ;BRANCH IF NO CUSSING DETECTED
- // GOTO CLOSE_POPON_RET ; ELSE, RETURN
- if(tvg_flags & CUSSING) goto CLOSE_POPON_RET;
- // ;*** UNMUTE AUDIO ***
- // CALL CHECK_TO_UNMUTE ;CHECK TO UNMUTE AUDIO
- check_to_unmute();
- // ;*** CHECK TO TURN OFF CAPTIONS ***
- // BTFSS IO_MAP,CC_CUSSING ;BRANCH IF "CC ONLY ON CUSSING"
- // GOTO CLOSE_POPON_RET ; ELSE, GOTO RETURN
- if(!(io_map & CC_CUSSING)) goto CLOSE_POPON_RET;
- fsr[0]=CCCMD_MISC; // replace POPOFF with Erase
- fsr[1]=CCCMD_ENM; // non-displayed memory command
- tvg_flags |= CMD_SUBST;
- // MOVLW OSDCMD_OENM ;ERASE NON-DISPLAYED MEMORY
- // CALL PUT_TO_OSD
- CLOSE_POPON_RET: // PREPARE TO RETURN FROM CLOSE_POPON
- // BCF PRG_STATUS_2,CUSSING ;ASSUME NEXT CAPTION HAS NO CUSSING
- // GOTO PROCESS_CC_POPOFF_0 ;GO BACK TO PROCESS_POPOFF
- tvg_flags &= ~CUSSING;
- goto PROCESS_CC_POPOFF_0;
- //******************************************************************************
- //* TABLE PROCESS_CC_JUMP
- //* DESC GOTO TABLE OF CLOSED CAPTION CONTROL CODE
- //* INPUT: R1 LS-NIBBLE = TABLE INDEX
- //* WARNING: MUST NOT CROSS PAGE
- PROCESS_CC_JUMP:
- // MOVLW HIGH PROCESS_CC_JUMP ;HIGH BYTE OF JUMP TABLE --> PCLATH
- // MOVWF PCLATH
- // MOVLW 0FH ;MASK FOR LOWER 4 BITS --> W
- // ANDWF R1,W ;LOWER NIBBLE OF R1 --> W
- // ADDWF PCL,ITSELF ;JUMP TO PROCESS CTRL CODES VIA PAC:2
- // ;(SEE FCC15.119 MISC CTRL CODES)
- switch(r1) {
- case 0x20: goto PROCESS_CC_POPON; // 20: JUMP TO POPON CODE
- case 0x21: goto PROCESS_CC_BKSP; // 21: JUMP TO BKSP CODE
- case 0x22: goto PROCESS_CC_RET; // 22: NOT USED - SKIP IT
- case 0x23: goto PROCESS_CC_RET; // 23: NOT USED - SKIP IT
- case 0x24: goto PROCESS_CC_DER; // 24: JUMP TO DER CODE
- case 0x25: goto PROCESS_CC_RU2; // 25: JUMP TO RU2 CODE
- case 0x26: goto PROCESS_CC_RU3; // 26: JUMP TO RU3 CODE
- case 0x27: goto PROCESS_CC_RU4; // 27: JUMP TO RU4 CODE
- case 0x28: goto PROCESS_CC_FON; // 28: JUMP TO FON CODE
- case 0x29: goto PROCESS_CC_RDC; // 29: JUMP TO RDC CODE
- case 0x2A: goto PROCESS_CC_TR; // 2A: JUMP TO TR CODE
- case 0x2B: goto PROCESS_CC_RTD; // 2B: JUMP TO RTD CODE
- case 0x2C: goto PROCESS_CC_EDM; // 2C: JUMP TO EDM CODE
- case 0x2D: goto PROCESS_CC_CR; // 2D: JUMP TO CR CODE
- case 0x2E: goto PROCESS_CC_ENM; // 2E: JUMP TO ENM CODE
- case 0x2F: goto PROCESS_CC_POPOFF; // 2F: JUMP TO POPOFF CODE
- }
- }
- // Variation od original SEND_CC_CHAR
- // Simply performs check on cc char
- // *** TRY NOT TO SEND LONE PUNCT. ***
- //
- // IN: W Input CC Char
- // OUT: DUMMY Output CC Char, modified if necessary
- //
- void chk_cc_char( void ) {
- CHK_CC_CHAR:
- dummy=w; // SAVE CC CHAR --> DUMMY
- if( !(tvg_flags & NO_LETTERS ) ) goto CHK_CC_CHAR_0;
- if(chk_if_punct()) {
- dummy=0;
- return;
- }
- tvg_flags &= ~NO_LETTERS; // FLAG THAT 1ST GOOD CHAR IS FOUND
- CHK_CC_CHAR_0:
- if(w < ' ') {
- dummy=0;
- return;
- }
- }
- #endif //TV_GUARDIAN_ENABLE