00001 /* 00002 * OpenBIOS - free your system! 00003 * ( FCode tokenizer ) 00004 * 00005 * This program is part of a free implementation of the IEEE 1275-1994 00006 * Standard for Boot (Initialization Configuration) Firmware. 00007 * 00008 * Copyright (C) 2001-2005 Stefan Reinauer, <stepan@openbios.org> 00009 * 00010 * This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; version 2 of the License. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA 00022 * 00023 */ 00024 00025 /* ************************************************************************** 00026 * 00027 * Functions for Managing FCode Assignment Pointer and for 00028 * Detection of Overlapping-FCode Error in Tokenizer 00029 * 00030 * (C) Copyright 2006 IBM Corporation. All Rights Reserved. 00031 * Module Author: David L. Paktor dlpaktor@us.ibm.com 00032 * 00033 **************************************************************************** */ 00034 00035 /* ************************************************************************** 00036 * 00037 * The fact that the user is able to specify, at any time, the 00038 * next FCode number to be assigned introduces the risk that 00039 * a symbol might inadvertently be assigned an FCode that is 00040 * still in use by another symbol, which could lead to bizarre 00041 * and hard-to-trace failures at run-time. 00042 * 00043 * This module will support a means whereby to detect and report, 00044 * as an Error, overlapping FCode assignments. 00045 * 00046 * The task is further complicated by the fact that, under some 00047 * circumstances, "recycling" a range of FCodes can be done 00048 * safely, and the programmer may do so intentionally. 00049 * 00050 * We will define a way for the programmer to specify that FCode 00051 * assignments are being intentionally "recycled", and that 00052 * overlaps with previously-assigned FCodes are not to be 00053 * treated as Errors. We will not attempt to analyze whether 00054 * it is, indeed, safe to do so; the programmer who does this 00055 * is presumed to be sufficiently responsible. 00056 * 00057 **************************************************************************** */ 00058 00059 00060 /* ************************************************************************** 00061 * 00062 * Functions Exported: 00063 * reset_fcode_ranges (Re-)Initialize the range of assignable 00064 * FCode numbers and clear the records 00065 * of prevously-assigned ranges of FCodes 00066 * list_fcode_ranges Display a final report of assigned FCode 00067 * ranges at end of tokenization or when 00068 * the reset_fcodes() routine is called. 00069 * set_next_fcode Set the start of a new Range of FCode 00070 * numbers to be assigned. 00071 * assigning_fcode The next FCode number is about to be assigned; 00072 * test for out-of-bounds, overlap, etc. 00073 * errors. 00074 * bump_fcode Increment the next FCode number prior to the 00075 * next assignment. 00076 * 00077 **************************************************************************** */ 00078 00079 /* ************************************************************************** 00080 * 00081 * Revision History: 00082 * 06 Jun 06 -- Need became apparent after verification test 00083 * against existing device-drivers. 00084 * 00085 * 00086 **************************************************************************** */ 00087 00088 00089 /* ************************************************************************** 00090 * 00091 * Still to be done: 00092 * Detect and report when the Current Range stops overlapping 00093 * one particular Range and starts overlapping another. 00094 * 00095 * Detect and report when the Current Range overlaps more than 00096 * one Range at a time (e.g., if other Ranges themselves 00097 * overlap, and the Current Range is stepping through them) 00098 * but, again, only display one message per overlapped Range. 00099 * 00100 **************************************************************************** */ 00101 00102 00103 00104 /* ************************************************************************** 00105 * 00106 * Global Variables Imported 00107 * iname Name of current input file 00108 * lineno Line Number within current input file 00109 * 00110 **************************************************************************** */ 00111 00112 #include <string.h> 00113 #include <stdio.h> 00114 #include <stdlib.h> 00115 00116 #include "toke.h" 00117 #include "nextfcode.h" 00118 #include "errhandler.h" 00119 #include "stream.h" 00120 #include "scanner.h" 00121 00122 00123 /* ************************************************************************** 00124 * 00125 * Global Variables Exported 00126 * nextfcode The next FCode-number to be assigned 00127 * 00128 **************************************************************************** */ 00129 00130 u16 nextfcode; /* The next FCode-number to be assigned */ 00131 00132 /* ************************************************************************** 00133 * 00134 * Internal (Static) Structure: 00135 * fcode_range_t The record of a Range of assigned FCodes 00136 * 00137 * Fields: 00138 * fcr_start FCode number at the start of a this Range 00139 * fcr_end Last FCode number in this Range that has 00140 * actually been assigned. 0 if none made yet. 00141 * fcr_infile File name of where this Range was started 00142 * fcr_linenum Line number where this Range was started 00143 * fcr_not_lapped TRUE if an overlap error has not been reported 00144 * against this Range. Use this to prevent 00145 * issuing an Error message every time an 00146 * overlapping FCode is assigned; once per 00147 * Range is sufficient. 00148 * fcr_next Pointer to following entry in linked-list. 00149 * 00150 * We will keep the list of assigned FCode Ranges as a forward-linked, 00151 * rather than the more usual backward-linked, list for convenience 00152 * at listing-time. Otherwise, it doesn't make much difference. 00153 * 00154 **************************************************************************** */ 00155 00156 typedef struct fcode_range 00157 { 00158 u16 fcr_start; 00159 u16 fcr_end ; 00160 char *fcr_infile; 00161 int fcr_linenum; 00162 bool fcr_not_lapped; 00163 struct fcode_range *fcr_next; 00164 } fcode_range_t ; 00165 00166 00167 /* ************************************************************************** 00168 * 00169 * Internal Static Variables 00170 * ranges_exist TRUE if FCode Ranges have been created; 00171 * Prevents unnecessary overlap checking. 00172 * changes_listed TRUE if no changes to any of the Ranges 00173 * have taken place since the last time 00174 * a Listing was displayed. Prevents 00175 * unnecessary repetions (e.g., if a 00176 * reset_fcode_ranges() was called 00177 * right after an operation that causes 00178 * a Listing 00179 * 00180 * These four apply if no FCode Ranges have been created: 00181 * 00182 * range_start First FCode in the current first (only) range. 00183 * range_end Last FCode in current first (only) range that 00184 * has actually been assigned. 0 if none yet. 00185 * first_fcr_infile File name of where first (only) range started. 00186 * first_fcr_linenum Line number where first (only) range started. 00187 * 00188 * These two apply after FCode Ranges have been created: 00189 * 00190 * first_fc_range Pointer to the first entry in the linked 00191 * list of FCode Ranges. 00192 * current_fc_range Pointer to the entry in the linked list of 00193 * Ranges that contains the Current Range. 00194 * 00195 **************************************************************************** */ 00196 00197 static bool ranges_exist = FALSE; 00198 static bool changes_listed = FALSE; 00199 00200 static u16 range_start = FCODE_START; 00201 static u16 range_end = 0; 00202 static char *first_fcr_infile = NULL; 00203 static int first_fcr_linenum = 0; 00204 00205 static fcode_range_t *first_fc_range = NULL; 00206 static fcode_range_t *current_fc_range = NULL; 00207 00208 /* ************************************************************************** 00209 * 00210 * Function name: reset_fcode_ranges 00211 * Synopsis: (Re-)Initialize the range of assignable FCode numbers 00212 * and clear the records of prevously-assigned Ranges 00213 * 00214 * Inputs: 00215 * Parameters: NONE 00216 * Global Variables: 00217 * iname Name of current input file 00218 * lineno Line Number within current input file 00219 * Local Static Variables: 00220 * ranges_exist TRUE if FCode Ranges have been created 00221 * first_fc_range Pointer to First FCode Range 00222 * current_fc_range Pointer to the current Range 00223 * 00224 * Outputs: 00225 * Returned Value: NONE 00226 * Global Variables: 00227 * nextfcode Initialized to Standard start value 00228 * for user-assigned FCodes 00229 * Local Static Variables: 00230 * ranges_exist Cleared to FALSE 00231 * changes_listed Reset to FALSE 00232 * range_start Reset to Standard start value 00233 * range_end Reset to 0 00234 * first_fcr_infile Copy of iname 00235 * first_fcr_linenum Copy of lineno 00236 * first_fc_range Reset to NULL 00237 * current_fc_range Reset to NULL 00238 * Memory Allocated 00239 * For first_fcr_infile , which will have a copy of iname 00240 * When Freed? 00241 * The next time this routine is called. 00242 * Memory Freed 00243 * Any FCode Ranges that were in effect will be freed, and the 00244 * memory for their fcr_infile fields will be freed. 00245 * If iname has changed, memory for first_fcr_infile will 00246 * be freed before the new copy is made. 00247 * 00248 * Process Explanation: 00249 * This will be called either as part of normal initialization 00250 * or in response to a User-issued directive. 00251 * In the former case, it may be called twice: once before any 00252 * Source is examined, and once again in response to the first 00253 * (and only to the first) invocation of an FCode-Starter, at 00254 * which time the input file name and line number will be updated. 00255 * In the latter case, the calling routine will be responsible for 00256 * displaying any Advisory Messages and listings of previously 00257 * assigned FCode Ranges. 00258 * 00259 **************************************************************************** */ 00260 00261 void reset_fcode_ranges( void) 00262 { 00263 if ( ranges_exist ) 00264 { 00265 while ( current_fc_range != NULL ) 00266 { 00267 current_fc_range = first_fc_range->fcr_next; 00268 free( first_fc_range->fcr_infile); 00269 free( first_fc_range); 00270 first_fc_range = current_fc_range; 00271 } 00272 ranges_exist = FALSE; 00273 }else{ 00274 if ( first_fcr_infile != NULL ) 00275 { 00276 if ( strcmp( first_fcr_infile, iname) != 0 ) 00277 { 00278 free( first_fcr_infile); 00279 first_fcr_infile = NULL; 00280 } 00281 } 00282 } 00283 00284 changes_listed = FALSE; 00285 range_start = FCODE_START; 00286 range_end = 0; 00287 00288 if ( first_fcr_infile == NULL ) 00289 { 00290 first_fcr_infile = strdup( iname); 00291 } 00292 first_fcr_linenum = lineno; 00293 nextfcode = FCODE_START; 00294 } 00295 00296 /* ************************************************************************** 00297 * 00298 * Function name: list_fcode_ranges 00299 * Synopsis: Display an Advisory of assigned FCode ranges at 00300 * end of tokenization or upon reset_fcodes() 00301 * 00302 * Inputs: 00303 * Parameters: 00304 * final_tally TRUE if printing a final tally at 00305 * end of tokenization. 00306 * Global Variables: 00307 * verbose Do not print anything if not set. 00308 * nextfcode FCode next after last-assigned 00309 * Local Static Variables: 00310 * changes_listed If TRUE, only print new-line. 00311 * ranges_exist TRUE if more than one Range exists. 00312 * range_start FCode at start of only range 00313 * range_end Last FCode in only range; 0 if none. 00314 * first_fc_range Ptr to start of FCode Ranges list 00315 * 00316 * Outputs: 00317 * Returned Value: NONE 00318 * Local Static Variables: 00319 * changes_listed Set to TRUE. 00320 * Printout: 00321 * Printed to Standard Out on final tally, or to STDERR otherwise. 00322 * One of three formats: 00323 * 1 No FCodes assigned. 00324 * 2 Last assigned FCode = 0xXXX 00325 * 3 FCodes assigned: 00326 * [ No FCodes assigned in the range that started ... ] 00327 * [ From 0xXXX to 0xYYY ** in the range that started ... ] 00328 * (** = Indicator if the Range has an Overlap Error.) 00329 * 00330 * Process Explanation: 00331 * This is called to complete an Advisory or Standard-Out Message 00332 * that doesn't end in a new-line. 00333 * 00334 * Extraneous Remarks: 00335 * If we ever decide not to keep entries for Ranges in which no 00336 * assignments were made, let's not remove the code that lists 00337 * them. It's harmless to keep it around, and we remain ready... 00338 * 00339 **************************************************************************** */ 00340 00341 void list_fcode_ranges( bool final_tally) 00342 { 00343 if ( verbose ) 00344 { 00345 FILE *message_dest = ( final_tally ? stdout : ERRMSG_DESTINATION ); 00346 if ( changes_listed ) 00347 { 00348 fprintf(message_dest, "\n"); 00349 }else{ 00350 changes_listed = TRUE; 00351 00352 if ( INVERSE(ranges_exist) ) 00353 { /* List the first and only range */ 00354 if ( range_end == 0 ) 00355 { 00356 fprintf(message_dest, "No FCodes assigned.\n"); 00357 }else{ 00358 if ( range_start == FCODE_START ) 00359 { 00360 fprintf(message_dest, 00361 "Last assigned FCode = 0x%x\n", range_end); 00362 }else{ 00363 fprintf(message_dest, 00364 "FCodes assigned: 0x%x to 0x%x\n", 00365 range_start, range_end); 00366 } 00367 } 00368 /* We are done listing the first and only range */ 00369 }else{ /* List the collection of Ranges */ 00370 00371 /* Pionter to function returning void */ 00372 typedef void (*vfunct)(); 00373 00374 /* Function for the started_at() part of the message */ 00375 vfunct start_at_funct = 00376 ( final_tally ? print_started_at : started_at ); 00377 00378 00379 fcode_range_t *next_range = first_fc_range; 00380 00381 fprintf(message_dest, "FCodes assigned:\n"); 00382 00383 while ( next_range != NULL ) 00384 { 00385 if ( next_range->fcr_end == 0 ) 00386 { 00387 fprintf(message_dest, " None assigned"); 00388 }else{ 00389 fprintf(message_dest, " From 0x%x to 0x%x", 00390 next_range->fcr_start, next_range->fcr_end ); 00391 if ( INVERSE( next_range->fcr_not_lapped) ) 00392 { 00393 fprintf(message_dest, " ***Overlap***" ); 00394 } 00395 } 00396 fprintf(message_dest, " in the range"); 00397 (*start_at_funct)( 00398 next_range->fcr_infile, next_range->fcr_linenum ); 00399 00400 next_range = next_range->fcr_next; 00401 } 00402 } 00403 } 00404 } 00405 } 00406 00407 00408 /* ************************************************************************** 00409 * 00410 * Function name: set_next_fcode 00411 * Synopsis: Set the start of a new Range of FCode numbers 00412 * 00413 * Inputs: 00414 * Parameters: 00415 * new_fcode Start of the new range of FCodes 00416 * Global Variables: 00417 * nextfcode The next FCode-number to be assigned 00418 * iname Name of current input file 00419 * lineno Line Number within current input file 00420 * Local Static Variables: 00421 * ranges_exist TRUE if FCode Ranges have been created 00422 * range_start First FCode in the current (first 00423 * and only) range 00424 * range_end Last FCode in only range; 0 if none. 00425 * current_fc_range Pointer to the current Range if there 00426 * are more than one. 00427 * 00428 * Outputs: 00429 * Returned Value: NONE 00430 * Global Variables: 00431 * nextfcode Set to the start of the new range 00432 * Local Static Variables: 00433 * ranges_exist May be set to TRUE 00434 * first_fc_range May be initialized 00435 * current_fc_range May be initialized or moved 00436 * first_fcr_infile May be updated, may be made NULL 00437 * first_fcr_linenum May be updated, may be made irrelevant 00438 * range_start May be set to start of the new range 00439 * or rendered irrelevant 00440 * range_end Reset to 0 (by reset_fcode_ranges() ) 00441 * changes_listed Reset to FALSE 00442 * Memory Allocated 00443 * For new Range data structure; for copy of iname 00444 * When Freed? 00445 * By reset_fcode_ranges() 00446 * 00447 * Error Detection: 00448 * Not here. 00449 * The calling routine will detect and report attempts to set an 00450 * illegal new range. 00451 * Overlap with earlier Ranges will be detected and reported when 00452 * the FCode is actually Assigned. 00453 * 00454 * Process Explanation: 00455 * The calling routine will not call this routine with a new starting 00456 * FCode that is not legal per the Standard. 00457 * It may call with a new starting FCode that is equal to nextfcode 00458 * If no Ranges exist yet, and the new starting FCode is equal to 00459 * the current value of nextfcode , this is a continuation of 00460 * the first and only range; do not change the file name or line 00461 * number; just go away. 00462 * If no Ranges exist yet, and no FCode assignments have been made 00463 * in the current range, then this is a new start for the first 00464 * and only range; detect the latter condition by range_end == 0 00465 * Call the reset_fcode_ranges() routine to update the file name 00466 * and line number, then update the remaining variables for the 00467 * current (first and only) range, and you are done here. 00468 * If no Ranges exist yet, and if FCode assignments _have_ been made 00469 * in the current (first and only) range, create a data structure 00470 * for the first (and now no longer only) Range and point both 00471 * the first_fc_range and current_fc_range pointers at it. 00472 * Set the ranges_exist flag to TRUE. 00473 * If Ranges exist, whether from being newly-created, above, or from 00474 * earlier, create a data structure for the new Current Range 00475 * and move the current_fc_range pointer to point at it. If 00476 * the new starting FCode is equal to nextfcode we still want 00477 * to create a new Range that will be listed separately. 00478 * If no assignments were made within the Current Range, we will not 00479 * overwrite or delete it; it will be listed at the appropriate 00480 * time, and will be harmless in the overlap test. 00481 * 00482 * Extraneous Remarks: 00483 * We will trade off the strict rules of structured code here, 00484 * in exchange for ease of coding. 00485 * 00486 **************************************************************************** */ 00487 00488 void set_next_fcode( u16 new_fcode) 00489 { 00490 if ( INVERSE( ranges_exist) ) 00491 { /* The current range is the first and only. */ 00492 00493 if ( new_fcode == nextfcode ) 00494 { 00495 /* Do nothing here */ 00496 return; 00497 } 00498 00499 if ( range_end == 0 ) 00500 { /* No FCode assignments have been made in the current range */ 00501 /* This is still the first and only range. */ 00502 00503 reset_fcode_ranges(); /* Update file name and line number */ 00504 range_start = new_fcode; 00505 nextfcode = new_fcode; 00506 00507 /* We are done here */ 00508 return; 00509 00510 }else{ /* Create the data structure for the first Range */ 00511 first_fc_range = safe_malloc( sizeof( fcode_range_t), 00512 "creating first FCode Range" ); 00513 first_fc_range->fcr_start = range_start; 00514 first_fc_range->fcr_end = range_end; 00515 first_fc_range->fcr_infile = first_fcr_infile; 00516 first_fc_range->fcr_linenum = first_fcr_linenum; 00517 first_fc_range->fcr_not_lapped = TRUE; 00518 first_fc_range->fcr_next = NULL; 00519 00520 first_fcr_infile = NULL; 00521 first_fcr_linenum = 0; 00522 range_start = FCODE_START; 00523 range_end = 0; 00524 00525 current_fc_range = first_fc_range; 00526 00527 ranges_exist = TRUE; 00528 } 00529 } 00530 00531 /* Previous Ranges exist now for sure! */ 00532 current_fc_range->fcr_next = safe_malloc( sizeof( fcode_range_t), 00533 "creating new FCode Range" ); 00534 current_fc_range = current_fc_range->fcr_next; 00535 00536 nextfcode = new_fcode; 00537 current_fc_range->fcr_start = nextfcode; 00538 current_fc_range->fcr_end = 0; 00539 /* Will be filled in by first assignment */ 00540 current_fc_range->fcr_infile = strdup( iname); 00541 current_fc_range->fcr_linenum = lineno; 00542 current_fc_range->fcr_not_lapped = TRUE; 00543 current_fc_range->fcr_next = NULL; 00544 00545 changes_listed = FALSE; 00546 } 00547 00548 00549 /* ************************************************************************** 00550 * 00551 * Function name: find_overlap 00552 * Synopsis: Compare the FCode under test against existing 00553 * FCode Ranges and return a pointer to the 00554 * Range against which it overlaps, if any. 00555 * 00556 * Inputs: 00557 * Parameters: 00558 * test_fcode FCode to be tested 00559 * Global Variables: 00560 * 00561 * Local Static Variables: 00562 * ranges_exist If not TRUE, no need to test 00563 * first_fc_range Start of Ranges to test 00564 * current_fc_range Do not test Current Range 00565 * 00566 * Outputs: 00567 * Returned Value: Pointer to FCode Range in which an 00568 * overlap exists, or NULL if none. 00569 * 00570 * Error Detection: 00571 * The calling routine will treat any findings as it deems appropriate. 00572 * 00573 * Process Explanation: 00574 * A Range within which no assignments were made will never "hit" 00575 * the overlap test because its fcr_end field will be zero 00576 * and its fcr_start field will be non-zero; there's no 00577 * number that will be "between" them! 00578 * 00579 **************************************************************************** */ 00580 00581 static fcode_range_t *find_overlap( u16 test_fcode) 00582 { 00583 fcode_range_t *retval = NULL; 00584 if ( ranges_exist ) 00585 { 00586 fcode_range_t *test_range = first_fc_range; 00587 while ( test_range != current_fc_range ) 00588 { 00589 if ( ( test_fcode <= test_range->fcr_end ) && 00590 ( test_fcode >= test_range->fcr_start ) ) 00591 { 00592 retval = test_range; 00593 break; 00594 } 00595 test_range = test_range->fcr_next; 00596 } 00597 } 00598 00599 return( retval); 00600 } 00601 00602 00603 /* ************************************************************************** 00604 * 00605 * Function name: assigning_fcode 00606 * Synopsis: Commit the next FCode number to be assigned; 00607 * test for out-of-bounds, overlap, etc. errors. 00608 * 00609 * Inputs: 00610 * Parameters: 00611 * 00612 * Global Variables: 00613 * nextfcode 00614 * Local Static Variables: 00615 * ranges_exist TRUE if FCode Ranges have been created 00616 * first_fc_range First entry in linked list of Ranges. 00617 * current_fc_range List entry for Current Range. 00618 * 00619 * Outputs: 00620 * Returned Value: NONE 00621 * Global Variables: 00622 * Local Static Variables: 00623 * changes_listed Reset to FALSE 00624 * One of these two will be set to nextfcode 00625 * range_end ... if ranges_exist is FALSE 00626 * current_fc_range->fcr_end ... if ranges_exist is TRUE 00627 * 00628 * Error Detection: 00629 * FATAL if the value of nextfcode is larger than the legal 00630 * maximum for an FCode 00631 * ERROR if the value of nextfcode falls within one of the 00632 * existing Ranges (other than the current one, of course) 00633 * 00634 **************************************************************************** */ 00635 00636 void assigning_fcode( void) 00637 { 00638 if ( nextfcode > FCODE_LIMIT ) 00639 { 00640 /* Let's give a last summarization before we crap out */ 00641 tokenization_error( INFO, ""); 00642 list_fcode_ranges( FALSE); 00643 00644 tokenization_error( FATAL, 00645 "Too many definitions. " 00646 "Assigned FCode exceeds limit " 00647 "specified by IEEE-1275."); 00648 /* 00649 * No need to return() from here. 00650 * FATAL error exits program. 00651 */ 00652 } 00653 00654 changes_listed = FALSE; 00655 00656 if ( INVERSE(ranges_exist) ) 00657 { /* No Overlap Error checking needed here. */ 00658 range_end = nextfcode; 00659 }else{ 00660 current_fc_range->fcr_end = nextfcode; 00661 00662 /* Detect and report Overlap Error only once per Range */ 00663 if ( current_fc_range->fcr_not_lapped ) 00664 { 00665 fcode_range_t *found_lap = find_overlap( nextfcode); 00666 if ( found_lap != NULL ) 00667 { 00668 tokenization_error( TKERROR, 00669 "Assigning FCode of 0x%x, " 00670 "which overlaps the range", nextfcode); 00671 started_at( found_lap->fcr_infile, found_lap->fcr_linenum); 00672 00673 current_fc_range->fcr_not_lapped = FALSE; 00674 } 00675 } 00676 } 00677 00678 } 00679 00680 00681 /* ************************************************************************** 00682 * 00683 * Function name: bump_fcode 00684 * Synopsis: Increment the next assignable FCode number 00685 * prior to the next assignment. 00686 * 00687 * Inputs: 00688 * Parameters: NONE 00689 * Global Variables: 00690 * nextfcode The next FCode-number to be assigned 00691 * 00692 * Outputs: 00693 * Returned Value: NONE 00694 * Global Variables: 00695 * nextfcode Incremented 00696 * 00697 * Extraneous Remarks: 00698 * This looks like a no-brainer now, but if we ever need this 00699 * function to perform any more sophisticated background 00700 * activity, we can limit the scope of our modifications 00701 * to this routine. 00702 * 00703 **************************************************************************** */ 00704 00705 void bump_fcode( void) 00706 { 00707 nextfcode++; 00708 }