home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / BDSC / BDSC-3 / V145.DOC < prev    next >
Text File  |  2000-06-30  |  23KB  |  406 lines

  1.  
  2.  
  3.                           BDS C User's Guide Addenda
  4.                        v1.45 Edition --  December, 1981
  5.  
  6.                                   Leor Zolman
  7.                                   BD Software
  8.                                 33 Lothrop st.
  9.                         Brighton, Massachussetts 02135
  10.  
  11.  
  12. Here are the bug fixes and extensions for BDS C version 1.45.  
  13.  
  14. Note: If you are running under MP/M II, be sure to see item 10 below!  
  15.  
  16.  
  17.  
  18.  
  19. 0.   Expressions of the form 
  20.      
  21.              !(expr || expr)
  22.         or   !(expr && expr)
  23.  
  24.      may  not  have  worked  correctly  when  a  VALUE  was  required  for  the
  25.      expression; i.e., when used in some way other than in a flow control test.
  26.      For example, 
  27.      
  28.              x = !(a || b);
  29.  
  30.      might have failed, but 
  31.      
  32.              if (!(a || b)) return 7;
  33.  
  34.      would have worked, since the expression was used for flow control.  
  35.  
  36.  
  37. 1.   Declarations  of  pointer-to-function  variables for functions returning a
  38.      CHARACTER value caused only one byte of  storage  to  be  reserved for the
  39.      pointer, instead of two bytes (all pointers-to-functions require two bytes
  40.      of storage, by virtue of being pointers). For example, in the sequence:  
  41.      
  42.              char c1, (*ptrfn)(), c2;
  43.              ...
  44.              ptrfn = &getc;
  45.  
  46.      the  assignment  to  `ptrfn' would have incorrectly overwritten  the  `c2'
  47.      character variable, since  only  one  byte would have been reserved on the
  48.      stack for the `ptrfn' variable while the  assignment  operation would have
  49.      assumed there were two bytes reserved.  
  50.  
  51.  
  52. 2.   A  bug  in  the  ternary  operator evaluator (?: expressions)  caused  the
  53.      high-order  byte of a 16-bit  result  to  be  incorrectly  zeroed  in  the
  54.      following situation: given a ternary expression of the form 
  55.      
  56.              e1 ? e2 : e3
  57.  
  58.      where `e2' evaluated to a 16-bit value (int, unsigned or pointer) and `e3'
  59.      evaluated to a character value (type char only), the entire expression was
  60.      treated as having type char...so if `e1' was true and `e2' was bigger than
  61.      255, then the  value of the expression ended up as only the low-order byte
  62.      of the value of `e2'. For version 1.45, whenever `e2' and `e3' do not BOTH
  63.      evaluate to character  values  the  type  of  the  overall  expression  is
  64.      guaranteed not to be char.  
  65.  
  66.  
  67. 3.   A  sequence  of  two `!' (logical `not') operators in a row did not always
  68.      produce the correct result in an expression. For example, 
  69.      
  70.              x = !!n;                /* convert n to a logical (0 or 1) value */
  71.  
  72.      might have produced the wrong result (0 instead of 1, or vice-versa).  
  73.  
  74.  
  75. 4.   A  stack-handling  bug   in  CC2  caused  problems  at  run  time  when  a
  76.      sufficiently complex sub-expression appeared in any but the final position
  77.      of an expression involving  the  comma  operator  (",").  For example, the
  78.      following statement would not have worked correctly:  
  79.      
  80.              for (i = 0; i < 10; x += y, i++) ...
  81.  
  82.  
  83.  
  84. 5.   CC1  has not been recognizing illegal octal character constants  as  such;
  85.      digits such as `8' and `9' within an octal constant will now draw an error
  86.      in cases  where  they  would have been ignored before. Also, certain other
  87.      forms of illegal constants (aside from character constants) are now better
  88.      diagnosed than before.  
  89.  
  90.  
  91. 6.   I  found  one more case where  an  internal  table  overflow  during  code
  92.      generation  was  not  detected,  causing the final command file to bomb as
  93.      soon as it was executed (either by  crashing  the  machine  or immediately
  94.      re-booting.)  This  occurred when a single large function containing  many
  95.      string constants was compiled. All fixed now.  
  96.  
  97.  
  98. 7.   An  extension  to the linker:  CLINK  now  recognizes  "DEFF3.CRL"  as  an
  99.      automatic library file, similar to DEFF.CRL and DEFF2.CRL. Note that there
  100.      is NO DEFF3.CRL  file  included  with  the BDS C package; this feature has
  101.      been added to allow you to fit more custom  functions  into  your  library
  102.      than  just  what  fits in DEFF.CRL and DEFF2.CRL (which are getting rather
  103.      full.) 
  104.  
  105.      Also, CLINK will now search ALL default library files (DEFF.CRL, DEFF2.CRL
  106.      and  DEFF3.CRL  [if  it  exists])  when  a  carriage-return  is  typed  in
  107.      interactive mode.  Previously,  only  the  file  DEFF.CRL  was searched in
  108.      response to carriage-return.  
  109.  
  110.  
  111. 8.   It  has been brought to my attention that the ^Q-CR sequence  required  by
  112.      CLINK  in  interactive  mode  (to abort the linkage in progress) cannot be
  113.      typed in under MP/M systems, since  ^Q is used to detach a process. If you
  114.      are running MP/M, then just type control-C  instead  of  ^Q-CR;  this will
  115.      also  work  for  CP/M systems...the only difference is that when ^Q-CR  is
  116.      used, then any currently  active "submit file" processing is automatically
  117.      aborted by CLINK before returning  to  command  level, as a convenience (I
  118.      assume that if you abort the linkage, you don't want to continue with your
  119.      submit file...). Under MP/M, you'll have to type characters quickly at the
  120.      keyboard (after ^C-ing CLINK) to abort any pending  submit  file activity.
  121.  
  122.  
  123. 9.   A slight bug in CLIB.COM (The C Library manager program) made  it  hard to
  124.      exit  CLIB  from  within  a  submit  file  (assuming XSUB is in use).  The
  125.      problem was that CLIB requires a confirmation  character, `y', to be typed
  126.      after  the  `quit'  command is given.  CLIB was getting  the  confirmation
  127.      character by doing a single direct BDOS console input call, which required
  128.      the user to manually  type  in  the  letter before any pending submit file
  129.      processing could continue. This has been  fixed  by  having  CLIB  get  an
  130.      entire  line  of  input  (using BDOS call 10) when seeking a confirmation;
  131.      now the `y' may be inserted  into  submit  files.  Note  that  the  `quit'
  132.      command  and  the  `y' confirmation must be placed on separate consecutive
  133.      lines in the submit  file. If not using a submit file, the only difference
  134.      is that now a carriage-return is required after typing the `y'.  
  135.  
  136.      Another minor problem  with  CLIB: function names longer than 8 characters
  137.      were not being truncated when  entered  for  operations  such as renaming,
  138.      resulting  in  too-long  CRL  file  directory entries. All names  are  now
  139.      properly limited to 8 characters.  
  140.  
  141.  
  142. 10.  A problem with file I/O under MP/M Version  II  has  come up: The run-time
  143.      package routine "vclose", called by the library function  "close" whenever
  144.      a  file  needs to be closed, has been optimizing for files open  only  for
  145.      reading by  NOT  actually performing a "close" operation through the BDOS.
  146.      This worked fine under  CP/M,  because  CP/M  didn't care whether or not a
  147.      file that has had no changes made to it was ever  closed;  MP/M II, on the
  148.      other  hand, DOES seem to want such files to be explicitly closed...so  by
  149.      running  many  programs  that  didn't  close  their Read-only files, BDS C
  150.      programs eventually caused MP/M to not allow any  more files to be opened.
  151.  
  152.      This  problem  has  been  fixed by adding a conditional  assembly  symbol,
  153.      called "MPM2", to the CCC.ASM  source  file. If you are running under MP/M
  154.      II, you should set the "MPM2" equate to  true  (1) and reassemble CCC.ASM,
  155.      yielding  a new C.CCC after loading and renaming  (you  should  only  need
  156.      ASM.COM for this, although MAC.COM works also). The change does NOT affect
  157.      the size of  C.CCC,  so  the libraries do not have to be reassembled as is
  158.      usually the case when the  run-time  package  is  customized.  The  change
  159.      simply causes a single conditional jump to be turned into three nop's,  so
  160.      that  ALL  files  are  always  closed,  instead  of only the ones open for
  161.      writing.  My apologies to MP/M users who may have had  confusing  troubles
  162.      because of this bug.  
  163.  
  164.  
  165. 11.  A bug was found in the `_scn' library function (affecting `scanf'): when a
  166.      lone carriage-return  (newline)  was  typed  in  response to a "%s" format
  167.      conversion, the format conversion was totally ignored.    This  caused the
  168.      target  string to remain unchanged from its previous contents, instead  of
  169.      correctly having a null string (consisting of a single zero byte) assigned
  170.      to it.  
  171.  
  172.  
  173. 12.  A bug was  found  in  the  `_spr'  library  function  (affecting `printf',
  174.      `sprintf', and `fprintf'): The default field width value  was 1, causing a
  175.      null string to be printed as a single space when the standard  "%s" format
  176.      conversion was used. For example, the statement:  
  177.      
  178.              printf("Here is a null string: \"%s\"\n","");
  179.  
  180.      would have produced the output:  
  181.      
  182.              Here is a null string: " "
  183.  
  184.      instead of:  
  185.      
  186.              Here is a null string: ""
  187.  
  188.      The default field width value has been changed to 0, so null strings  will
  189.      now  print  correctly.  An explicit field width may always be given in any
  190.      format conversion, of course.  
  191.  
  192.  
  193. 13.  When the library function  "sprintf"  (formatted  output  directly  into a
  194.      memory buffer) is used, a null byte is appended onto the end of the output
  195.      text.  I'm  not  absolutely  sure  whether  or  not  this  is  a "desired"
  196.      characteristic;  at  least one user has complained about it, but it  turns
  197.      out that "sprintf" on  the  large-scale  Unix system I have access to does
  198.      the same thing and I can think of applications  where the trailing null is
  199.      useful. So, the null stays in.  
  200.  
  201.  
  202. 14.  In  several  library functions, as well as at one point  in  the  run-time
  203.      package, calls  were  made to BDOS function number 11 (interrogate console
  204.      status) followed by an  "ani  1"  instruction  to  test bit 0 of the value
  205.      returned by BDOS. I've been told that on some systems,  testing  bit  0 is
  206.      not  sufficient  since  sometimes values other than 0 and 1 (or 0 and 255)
  207.      are returned. SO, all such  sequences  have  been changed to do an "ora a"
  208.      instead  of  an  "ani  1",  so  that  a return value  of  exactly  00h  is
  209.      interpreted as "no character ready" and  any other value is interpreted as
  210.      "yes,  there  is  a  character  ready". The library  functions  that  were
  211.      modified this way are: `kbhit', `putchar',  `srand1', `nrand', `sleep' and
  212.      `pause'.  The sequence to clear console status  in  the  run-time  package
  213.      (CCC.ASM),  near the label "init:", has likewise been changed (but a "nop"
  214.      instruction was  added  to  keep  all  addresses  consistent  with earlier
  215.      versions of the run-time package.) 
  216.  
  217.  
  218. 15.  When  customizing  the  run-time  package (CCC.ASM) with the "cpm"  symbol
  219.      equated  to zero, several symbols (named  "SETNM"  and  "SETNM3",  at  the
  220.      routine labeled  "PATCHNM") were undefined;  this has been fixed by adding
  221.      some conditional assembly directives to insure that the labels in question
  222.      are not referenced  under  non-"cpm" implementations, while the total code
  223.      size remains constant so that  the  addresses  of  later  run-time package
  224.      utility subroutines stay exactly the same for all implementations.  
  225.  
  226.  
  227. 16.  A  problem  with  the "bdos" library function has come up that  is  rather
  228.      tricky, since it is  system-dependent: A program that runs correctly under
  229.      a normal Digital Research CP/M system might NOT run under MP/M or SDOS (or
  230.      who knows how many other  systems)  if  the  "bdos"  function  is  used. A
  231.      typical symptom of this problem is that upon character output, a character
  232.      on  the  keyboard needs to be hit once in order to make each character  of
  233.      output appear.  
  234.  
  235.      To understand  the  problem,  we must first understand exactly how the CPU
  236.      registers are supposed to be set  after  an  operating  system  BDOS call.
  237.      Normal  CP/M  behavior  (which  the  C  library function "bdos" had always
  238.      assumed) is for registers A and L to contain  the  low-order  byte  of the
  239.      return value, and for registers B and H to contain the high order byte  of
  240.      a  return  value (which is zero if the return value is only one byte). The
  241.      CP/M interface guide explicitly states that "A == L and B == H upon return
  242.      in all cases",  and  I  figured  that  just in case CP/M 1.4 or some other
  243.      system didn't put the values in H and L  from B and A, I'd have the "bdos"
  244.      function copy register A into register L and copy register B into register
  245.      H, to make SURE the value is in HL (where  the return value must always be
  246.      placed by a C library function.) 
  247.  
  248.      Not  all systems actually FOLLOW this convention.  Under  MP/M,  H  and  L
  249.      always  contain the correct value but B does not! So when B is copied into
  250.      H, the wrong  value  results.  So,  the way to make "bdos" work under both
  251.      CP/M 2.2 and MP/M was to discontinue  copying  B  and  A into H and L, and
  252.      just assume the value will always be correctly left in HL  by  the system.
  253.      This  was  done  for  v1.45, so at least CP/M and MP/M are taken care  of,
  254.      but...  
  255.  
  256.      Under SDOS (and perhaps  other  systems), register A is sometimes the ONLY
  257.      register to contain a meaningful  return  value.  For example, upon return
  258.      from a function 11 call (interrogate console  status),  the  B,  H  and  L
  259.      registers  were all found to contain garbage.  So if no copying is done in
  260.      this case, the  return  value  never  gets  from  A to L and the result is
  261.      wrong;  but if B is copied into H along with A getting  copied into L, the
  262.      result is still wrong because B contains garbage.  Evidently  the only way
  263.      to get function 11 to work right under SDOS is to have the "bdos" function
  264.      copy  register A into L and ZERO OUT the H register before returning...but
  265.      then many  other  system  calls  which  return  values  in H wouldn't work
  266.      anymore.  And  that  is the problem: You can please SOME systems  ALL  the
  267.      time, but not ALL systems  all  the  time  with  only  one standard "bdos"
  268.      function!  
  269.  
  270.      The way I left "bdos" for version 1.45 was so that it works  with CP/M and
  271.      MP/M (i.e., no register copying is done at all...HL is assumed  to contain
  272.      the  correct  value).  You  might  want to make a note in the User's Guide
  273.      library section (page 30) to the effect  that  A  and  B  are now ignored.
  274.      This,  of  course,  won't  work in all cases under SDOS and perhaps  other
  275.      systems...in those cases, you  need  to  either use the "call" and "calla"
  276.      functions  to  perform the BDOS call, or create  your  own  assembly-coded
  277.      version(s) of the  "bdos" function (with MAC.COM, CMAC.LIB and BDS.LIB) to
  278.      perform the correct  register manipulation sequences for your system. Note
  279.      that it may take more  than one such function to cover all possible return
  280.      value register configurations.  
  281.  
  282.  
  283. 17.  The "creat" library function  had been creating new files and opening them
  284.      for writing ONLY; this caused some confusion, so `creat' has been modified
  285.      to open files for both reading  AND  writing  following  creation.  PLEASE
  286.      MAKE  A  NOTE  OF  THIS  UNDER  THE `CREAT' ENTRY IN THE STANDARD  LIBRARY
  287.      SECTION OF THE BDS C USER'S GUIDE.  
  288.  
  289.  
  290. 18.  The "execv" function has been changed  to  return  ERROR  (-1)  on  error,
  291.      instead  of forcing an error message ("Broken pipe") to be printed to  the
  292.      standard error  device.  The  reason  I originally had it printing "Broken
  293.      Pipe" was because I was too lazy to figure  out how to fix the stack after
  294.      passing all the arguments; following some justified  bitching  from  Scott
  295.      Layson  I  went  in  there  and  fixed it so it does something reasonable.
  296.      PLEASE MAKE A NOTE OF THIS UNDER THE `EXECV' ENTRY IN THE STANDARD LIBRARY
  297.      SECTION OF THE BDS C USER'S GUIDE.  
  298.  
  299.  
  300. 19.  The DIO (directed I/O and pipes) package  contained  an  obscure bug: if a
  301.      pipe operation was aborted before completion, leaving a "TEMPIN.$$$"  file
  302.      in  the  directory,  then the next pipe operation performed had gotten its
  303.      own output mixed up with  the output of the aborted pipe....the old output
  304.      was used as input to the new  next  command,  and the new output was lost.
  305.      The new DIO.C has been fixed. (Note: DIO.C has  also been slightly changed
  306.      to  properly  interact  with  the  new  version  of  the  "execv"  library
  307.      function.) 
  308.  
  309.  
  310. 20.  Another  change has been made to the DIO package: the "getchar"  function,
  311.      when used  without  input redirection to read characters directly from the
  312.      console, had not allowed for line editing in previous versions. I.e., each
  313.      character was obtained  by a direct BDOS call and none of the special line
  314.      editing characters (delete,  ^R,  ^U,  etc.)  were recognized. For version
  315.      1.45, an optional line buffer mechanism has been  added to the DIO package
  316.      so lines of console input can be fetched at one time  by  using  the "read
  317.      console  buffer"  BDOS  call  and  all editing characters now function  as
  318.      expected.  Operation of the package  using buffered console input is still
  319.      the  same  as  before,  except  for one thing:  to  enter  an  end-of-file
  320.      character (control-Z), it is now  necessary to also type a carriage-return
  321.      after the control-Z.  
  322.  
  323.      To  enable console input buffering when  using  the  DIO  library,  it  is
  324.      necessary to un-comment a line in the DIO.H file and re-compile DIO.C. See
  325.      the comments in DIO.C for more information.  
  326.  
  327.  
  328. 21.  The special  case handler for the code generator has been improved to more
  329.      efficiently handle  relational  binary operations where exactly one of the
  330.      operands  is  a constant. The operators  affected  are:  "<",  ">",  "<=",
  331.      ">=","=="  and  "!=",  for  both  signed  and  unsigned  data  types.  The
  332.      improvement is mainly  in  the  speed  of  execution  of such comparisons;
  333.      statements such as:  
  334.      
  335.              if (i < 1234) ...
  336.  
  337.      execute much faster. This results in speedier execution  of  programs such
  338.      as the Seive of Eratosthenes benchmark in the September '81 issue of BYTE:
  339.      the  current  version of BDS C, using the -e and -o compiler options  with
  340.      variables made  external,  does  it  in  15.2  seconds (see SIEVE.C on the
  341.      distribution disk.) 
  342.  
  343.      Also, multiplication by a constant that is a low  power of 2 (2,4,8,16) is
  344.      now  done  by  DAD  H sequences instead of calls to the  run-time  package
  345.      multiply routine [so  that  expressions  such as (i * 8) and (i << 3) each
  346.      compile to the same code].  
  347.  
  348.  
  349. 22.  Two new functions have been added to the standard library:  
  350.      
  351.          int setjmp(buffer)
  352.          char buffer[JBUFSIZE]; 
  353.      
  354.          longjmp(buffer,val)
  355.          char buffer[JBUFSIZE];
  356.  
  357.      When "setjump" is called, the current processor  state  is  saved  in  the
  358.      JBUFSIZE-byte  buffer  area  whose  address  is  passed  as  the  argument
  359.      ("JBUFSIZE"  is  defined  in  BDSCIO.H),  and a value of zero is returned.
  360.      Whenever a subsequent "longjump" call is performed  (from  ANYWHERE in the
  361.      current  function  or  any  lower-level  function)  with  the same  buffer
  362.      argument,  the  CPU  state  is  restored  to that which it was during  the
  363.      "setjmp" call, and the program behaves as if  control  were just returning
  364.      from  the  "setjmp" function, except that the return value  this  time  is
  365.      "val" as passed  to "longjmp".  A typical use of setjmp/longjmp is to exit
  366.      up through several  levels  of  function  nesting without having to return
  367.      through  EACH  level  in sequence, to make sure  that  a  particular  exit
  368.      routine (e.g., the directed  I/O "dioflush" function) is always performed.
  369.      It is a nifty facility that should  have  been  available long ago.  THESE
  370.      FUNCTIONS ARE NOT DOCUMENTED IN THE BDS C USER'S  GUIDE;    PLEASE  MAKE A
  371.      NOTE OF THEM IN THE STANDARD LIBRARY SECTION OF THE GUIDE.  
  372.  
  373.  
  374. 23.  A  new  linker  for  BDS C called "L2" (a substitute for CLINK.COM) is now
  375.      available from the BDS  C  User's  Group.  L2, written by Scott Layson (of
  376.      Mark of the Unicorn) in BDS C, has several interesting features:  
  377.  
  378.           1.   L2 can link programs that are up to  about 8K larger than CLINK:
  379.                if there isn't enough room in memory to  hold the entire program
  380.                while building an image in memory, L2 performs  a disk-buffering
  381.                second pass.  This means that the resulting COM files  can be as
  382.                large as the entire available TPA on the target machine.  
  383.  
  384.           2.   The number of functions per program is no longer limited to 255.
  385.  
  386.           3.   While  CLINK  uses jump tables at the beginning of functions  to
  387.                resolve references to other functions, L2 totally eliminates the
  388.                jump tables and  instead  generates  direct external calls. This
  389.                shortens programs by anywhere from 3%  to  10%,  and also speeds
  390.                them up a little.  
  391.  
  392.           4.   Since L2 is written in C, you can customize it yourself.  
  393.  
  394.      The L2 package comes with source code, a special overlay generator program
  395.      and documentation. It is available to BDSCUG members for the  nominal cost
  396.      of media and shipping (currently $8). See the next note for information on
  397.      joining the BDSCUG.  
  398.  
  399.  
  400. 24.  The  BDS C User's Group membership forms should now be included  with  the
  401.      BDS C package...this makes life easier for everyone, since it is no longer
  402.      necessary  to  write to the Group first just to ask for forms before being
  403.      able to order library  disks. BDS C User's Group members receive the Group
  404.      newsletter approximately  6  times  per year, and are entitled to compiler
  405.      updates and library disks for low prices (typically $8 per disk).  
  406.