home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / compiler / small_c / cb / sources / smallc.doc < prev    next >
Encoding:
Text File  |  1985-06-24  |  36.3 KB  |  1,424 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.        I.  INTRODUCTION
  10.  
  11.        Welcome to Small-c:PC.  Small-c:PC is a compiler that runs
  12.        under PC-DOS on the IBM Personal    Computer (PC).    The source input
  13.        to the compiler is written in small-c, a    subset of the C
  14.        programming language.  The compiler outputs symbolic assembly
  15.        language    code that can be assembled on the PC using the ASM or
  16.        MASM assembler programs available from IBM.
  17.  
  18.        The reference manual    for C is THE C PROGRAMMING LANGUAGE book
  19.        published by Prentice-Hall and authored by Brian    W.  Kernighan
  20.        and Dennis M.  Ritchie.    The original compiler for Small-c was
  21.        written by Ron Cain as a    personal project (see Dr.  Dobb's
  22.        Journal,    #45, Volume V, Number 5    for a description of small-c).
  23.        A CP/M version of the compiler for the Intel 8080 is being
  24.        distributed by The Code Works, 5266 Hollister, Suite 224, Santa
  25. More ?
  26.  
  27.        Barbara,    California 93111 (805) 683-1585.
  28.  
  29.        After using the CP/M    version    of the compiler, we decided to
  30.        port it over to the IBM PC (so we could take some of our    small-c
  31.        programs    over with us).    The conversion effort was guided by a
  32.        desire to not alter the personality of the original small-c
  33.        compiler.  The objective    was to minimize    the effort required to
  34.        convert existing    small-c    programs to the    Small-c:PC environment.
  35.        We think    we have    been successful    since our small-c programs have
  36.        been converted to the PC    with few problems using    Small-c:PC.
  37.  
  38.        The compiler    was converted by first deciding    what the output
  39.        should look like    and then modifying it to generate code for the
  40.        Intel 8088 instead of the 8080.    In parallel, the run time
  41.        library was rewritten in    8088 assembly language to operate under
  42.        PC-DOS.    If you have The    Code Works run time library for    CP/M and
  43.        are interested in the differences between CP/M and PC-DOS, you
  44.        might take the time to compare our library with theirs.
  45.  
  46.        Most    of the compiler    conversion problems centered around
  47.        ASM's need for memory.  The goal    was to produce a tool that could
  48.        be used on a 64KB PC with two 160KB drives.  Since ASM cannot
  49.        deal with large programs    in a 64    KB configuration, the small-c
  50. More ?
  51.  
  52.        compiler    was modified to    produce    code that could    be assembled
  53.        separately and then put together    using LINK.  The original
  54.        small-c compiler    produces one large output file.     Small-c:PC can
  55.        produce multiple    output files (one for each input file).     These
  56.        files can be assembled separately using ASM and then LINKed
  57.        together.  This can significantly reduce    program    development
  58.        time, however, since only the modified file need    be recompiled in
  59.        the event of source code    changes.  It can then be assembled and
  60.        linked with existing object files.
  61.  
  62.        If you have more than 64KB, ASM can assemble    larger files.
  63.        With sufficient memory, you can work with larger    small-c    program
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75. More ?
  76.  
  77.                   - 2 -
  78.  
  79.  
  80.  
  81.        files.  The memory requirement for using    Small-c:PC, however, is
  82.        imposed by ASM, not by the Small-c:PC compiler.    Small-c:PC will
  83.        compile large programs quite nicely in 64KB.
  84.  
  85.        If you examine your distribution copy of the    compiler, named
  86.        CPCN.C, you will    notice that the    source code is marked so that it
  87.        can be broken into many smaller files.  The makers are small-c
  88.        comment statements written as:
  89.  
  90.                   /* ### cpcn-xx */
  91.  
  92.        Each    of these comment statements marks the start of a
  93.        separate    file.  We marked it this way so    that users with    only
  94.        64KB can    modify the compiler if they choose to do so.  It will be
  95.        necessary, however, to insert the proper    external declarations
  96.        into each file.    For those of you with more memory, it is a
  97.        simple matter to    generate a new version of the compiler after
  98.        making any source editing changes.
  99.  
  100. More ?
  101.  
  102.        We have also    distributed the    source code for    FORMAT,    a text
  103.        processor described in the book SOFTWARE    TOOLS by Brian W.
  104.        Kernighan and P.J.  Plauger and published by Addison-Wesley.
  105.        This program is written in small-c.  This manual    was produced
  106.        using it.  The file FORMAT.DOC contains a brief description of
  107.        the FORMAT program and how to use it.
  108.  
  109.        As a    final note before we get into the operational details of
  110.        the compiler you    should be aware    of the fact that it may    contain
  111.        bugs.  We have tested it    quite a    bit, but you know how those
  112.        little rascals can hide.     So beware, one    may sneak up and bite
  113.        you (usually in the wee hours at    the worst time).  If you find
  114.        any of these critters, please write us and describe the problem.
  115.        We have priced Small-c:PC to recover our    development cost only.
  116.        Please don't call us to discuss problems    over the phone.
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125. More ?
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147.                   - 3 -
  148.  
  149.  
  150. More ?
  151.  
  152.  
  153.        II.  OPERATING Small-c:PC
  154.  
  155.        The compiler    is initiated by    entering CPC in    response to the
  156.        PC-DOS command prompt A>.  The compiler clears the screen, greets
  157.        you and asks two    questions.  The    possible answers are contained
  158.        in parenthesis following    each question.    The capitalized    response
  159.        in the default taken if you press the ENTER key.     The first
  160.        question    asked is:
  161.  
  162.             Should I pause after an    error (y,N)?
  163.  
  164.        Answering Y to this question    causes the compiler to pause
  165.        after displaying    an error.  This    will give you an opportunity to
  166.        continue    the compilation    or not.     Moreover, in the event    of a lot
  167.        of screen activity during a compilation this insures that you
  168.        won't miss an error message.  The N response causes the compiler
  169.        to continue automatically after displaying an error.
  170.  
  171.        The second question asked is:
  172.  
  173.            Do you want the Small-c:PC-text to appear (y,N)?
  174.  
  175. More ?
  176.  
  177.        Answering Y to this question    causes the compiler to write the
  178.        input source code into the output file(s) as comment statements.
  179.        each small-c statement appears with a semicolon as the first
  180.        character (to make it a comment to ASM) followed    by the assembly
  181.        language    code generated by the compiler for that    statement.  This
  182.        interleaving of source code and generated code is very useful in
  183.        learning    how the    compiler implements various small-c statements.
  184.        Choosing    this option causes the output files to be larger,
  185.        however.     Answering N will cause    the compiler to    not write the
  186.        small-c source to the output file.
  187.  
  188.        The two previous questions are followed by requests for input
  189.        and output filenames.  There are    no default extensions supplied
  190.        by the compiler.     Each input file generates a separate output
  191.        file.
  192.  
  193.        You can break a large small-c program into separate smaller
  194.        files and feed these to the compiler.  Hopefully    ASM will be able
  195.        to swallow the resultant    output files without running out of
  196.        memory.    Again, if you have more    than 64KB, ASM should be able to
  197.        process a large output file.  In    this case you will not be forced
  198.        to divide a large small-c program into multiple files.
  199.  
  200. More ?
  201.  
  202.        The next    request    by the compiler    is?
  203.  
  204.                     Input filename?
  205.  
  206.        The small-c source code is contained    in the file you    name in
  207.        response    to this    question.  There is no default extension supplied
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.                   - 4 -
  220.  
  221.  
  222.  
  223.        by the compiler.
  224.  
  225. More ?
  226.  
  227.        A single function definition    cannot be spread out across
  228.        multiple    input files.  This is because the compiler assumes the
  229.        output file corresponding to each input file will be separately
  230.        assembled.  It writes extra assembly language statements    into
  231.        each output file    to support this.  A function spread across two
  232.        input files may not assemble correctly.    Also, due to the way the
  233.        compiler    handles    externals, it is possible that a function name
  234.        could be    multiply defined and the compiler not detect it.  This
  235.        can happen if the separate definitions occur in different input
  236.        files.  In this circumstance, the error will be detected    by LINK.
  237.  
  238.        The runtime library (CPCLIB.ASM) is not input to the    compiler
  239.        as in other incarnations    of small-c.  Instead, it is input to
  240.        LINK as just another object file.  LINK will bind all of    the
  241.        object inputs together to produce an execute (.EXE) file.
  242.  
  243.        If your response to the input filename request is the ENTER
  244.        key or a    space (as the first character),    the compiler terminates
  245.        and returns control to PC-DOS.  This is the way the compiler is
  246.        normally    ended.
  247.  
  248.        Following the input filename request is the question:
  249.  
  250. More ?
  251.  
  252.                    Output filename?
  253.  
  254.        The assembly    language generated by the compiler for the
  255.        previous    input file is written into the named file.  Normally
  256.        this file will have the extension .ASM (not supplied
  257.        automatically by    the compiler) since it will be input to    the
  258.        assembler.  If you press    ENTER instead of providing a file name,
  259.        the compiler will direct    its output to the display.  You    might
  260.        try this    initially to get a feel    for the    code the compiler
  261.        generates.
  262.  
  263.        Let's consider the interactions to compile a    sample program.
  264.        Suppose the program is broken into two files names "SAMPLE-1.C"
  265.        and "SAMPLE-2.C".  You should first format a PC-DOS data    disk and
  266.        copy over to it the following files.
  267.  
  268.        CPC.EXE           [from the Small-c:PC distribution disk]
  269.        CPCLIB.OBJ             "
  270.        SAMPLE-1.C             "
  271.        SAMPLE-2.C             "
  272.  
  273.        We assume the following files are on your system    disk which is in
  274.        drive A.
  275. More ?
  276.  
  277.  
  278.        ASM.EXE           [from your IBM supplied macro assembler disk]
  279.        LINK.EXE           [from your IBM supplied PC-DOS disk]
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.                   - 5 -
  292.  
  293.  
  294.  
  295.        Note:  You could    use MASM instead of ASM.
  296.  
  297.        Get started by entering the following (the disk you made    is in
  298.        drive B)    and drive B is the logged in disk.
  299.  
  300. More ?
  301.  
  302.        B>CPC                     [invoke the compiler]
  303.  
  304.        * * *  Small-C:PC  V1.1    * * *    [first line of a clear screen]
  305.  
  306.        By Ron Cain, Modified by    CAPROCK    SYSTEMS    for the    IBM PC
  307.  
  308.  
  309.        Distributed by:    CAPROCK    SYSTEMS, INC>
  310.             P.O. Box 13814
  311.             Arlington, Texas 76013
  312.  
  313.        PC-DOS Version N:  June,    1982
  314.  
  315.  
  316.        Should I    pause after an error (y,N)>?  Y         [You don't want
  317.                              to miss any]
  318.  
  319.        Do you want the Small-c:PC-text to appear (y,N)?     N    [no]
  320.  
  321.        Input filename?    SAMPLE-1.C
  322.  
  323.        Output filename?     SAMPLE-1.ASM
  324.        ====== main ()               [you know when it starts    on a new
  325. More ?
  326.  
  327.        ====== plc()               function]
  328.  
  329.        There were 0 errors in compilation.
  330.  
  331.        Input filename?    SAMPLE-2.C     [the program is stored in two
  332.                        separate    files]
  333.  
  334.        Output filename?     SAMPLE-2.ASM
  335.        ====== getname()
  336.  
  337.        There were 0 errors in compilation.
  338.  
  339.        Input filename?    [press ENTER]
  340.  
  341.  
  342.  
  343.        Notice that the two input files could have been processed in
  344.        separate    executions of the compiler.  SAMPLE-2.C    contains the
  345.        necessary external data declarations to inform the compiler about
  346.        referenced data allocated elsewhere.
  347.  
  348.         The    output files are assembled next.
  349.  
  350. More ?
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.                   - 6 -
  364.  
  365.  
  366.  
  367.        B>A:ASM SAMPLE-1,,NUL:,NUL:
  368.        B>A:ASM SAMPLE-2,,NUL:,NUL:
  369.  
  370.        Next, we want to produce an execute file.  You do this by
  371.        executing LINK.    Our example assumes LINK inputs    as required by
  372.        PC-DOS Version 1.1.  If you have    Version    2.0 your LINK inputs
  373.        will be slightly    different, but the results should be the same.
  374.        The order of the    object file names supplied to LINK is
  375. More ?
  376.  
  377.        immaterial.
  378.  
  379.        B>A:LINK    SAMPLE-1+SAMPLE-2+CPCLIB,SAMPLE,NUL:,NUL:
  380.  
  381.        They you    are ready to execute the small-c program.  This    is
  382.        accomplished by typing the .EXE file name.
  383.  
  384.        B>SAMPLE    SAMPLE-1.ASM
  385.  
  386.        The SAMPLE program provided on the distribution disk types a text
  387.        file onto the display.  It obtains the file name    to operate on
  388.        from the    command    line.
  389.  
  390.  
  391.        ERROR REPORTING
  392.  
  393.  
  394.        When the    compiler detects an error in the small-c program, it
  395.        displays    a message on the screen.  An example would be:
  396.  
  397.        Line 20,    main + 0: missing open paren
  398.        main)
  399.         ^
  400. More ?
  401.  
  402.  
  403.  
  404.        The error occurred on the 20-th line    in the input file.  The
  405.        function    being compiled was "main".  The    error occurred 0 lines
  406.        into the    function.  the error detected was a "missing open
  407.        paren".    The hat    character (^) shows where the compiler was at
  408.        character-wise when it detected the error.  The compiler
  409.        continues automatically if you answered N to the    first question
  410.        asked by    the compiler (see example above).  If you answered Y to
  411.        this questions, you will    see the    following message displayed.
  412.  
  413.                Continue (Y,n,g)  ?
  414.  
  415.        Pressing    Y (or just ENTER) causes the compiler to continue
  416.        processing the source input.  If    you type N, the    compiler
  417.        displays    the message
  418.  
  419.               Compilation aborted.
  420.  
  421.        and returns to PC-DOS.  If you answer G,    the compiler continues
  422.  
  423.  
  424.  
  425. More ?
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.                   - 7 -
  436.  
  437.  
  438.  
  439.        processing the source input, but    will no    longer pause after an
  440.        error.
  441.  
  442.        Pressing CTRL+BREAK at any time will    abort the compiler and
  443.        return you to PC-DOS.  If the compiler is terminated by
  444.        CTRL+BREAK, no input or output files are    closed.
  445.  
  446.  
  447.  
  448.  
  449.  
  450. More ?
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475. More ?
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486.  
  487.  
  488.  
  489.  
  490.  
  491.  
  492.  
  493.  
  494.  
  495.  
  496.  
  497.  
  498.  
  499.  
  500. More ?
  501.  
  502.  
  503.  
  504.  
  505.  
  506.  
  507.                   - 8 -
  508.  
  509.  
  510.  
  511.        III.  USING THE LIBRARY FUNCTIONS
  512.  
  513.        All of the modules whose entry point    names began with CC are
  514.        used to support the compiler generated code.  As    a user,    you will
  515.        probably    never use these    routines directly.  The    functions that
  516.        start with QZ are user callable.     They can be divided into PC-DOS
  517.        interface routines and system interfact routines.  The PC-DOS
  518.        interfact routines generally provide I/O    through    the operating
  519.        system.    The disk I/O functions buffer only one 512 byte    sector
  520.        at a time (each open file has its own sector buffer space,
  521.        however).  This combined    with the fact that the transfer    width
  522.        between a small-c program and the disk routines is only one byte
  523.        causes file I/O to be somewhat slow.  Also, the library routines
  524.        support only ASCII files.  Certain characters are given special
  525. More ?
  526.  
  527.        meanings.  AS a result, you can not manipulate binary files with
  528.        small-c programs.  These    file types include .OBJ, .EXE and .COM
  529.        files.
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550. More ?
  551.  
  552.  
  553.  
  554.  
  555.  
  556.  
  557.  
  558.  
  559.  
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575. More ?
  576.  
  577.  
  578.  
  579.                   - 9 -
  580.  
  581.  
  582.  
  583.        THE PC-DOS INTERFACE LIBRARY ROUTINES
  584.  
  585.  
  586.        The following presents examples to illustrate the PC-DOS
  587.        interface routines.  The    small-c    declarations are simply
  588.        illustrations of    what can be done.  There are myriad ways to
  589.        accomplish the same coding example.  The    PC-DOS function    numbers
  590.        mentioned in the    descriptions are given in decimal.
  591.  
  592.               int c;
  593.               char buffer[81];
  594.               char *name,*mode;
  595.               int *ptr;
  596.               int ax,ah,dx;
  597.               char *string;
  598.  
  599.  
  600. More ?
  601.  
  602.        1.  Read    a character from the keyboard.
  603.  
  604.                   c = getchar();
  605.  
  606.        Reads a character from the keyboard using PC-DOS function 1.
  607.        The character read is echoed back to the    display.  Extended ASCII
  608.        codes will require two calls to this function.  A second    call is
  609.        indicated if the    returned character is null.  If    the character
  610.        input is    a carriage return, a line feed is also echoed back to
  611.        the display.  If    the character is CTRL-Z, a -1 is returned
  612.        instead.
  613.  
  614.        2.  Write a character to    the display.
  615.  
  616.                   c = putchar(c);
  617.  
  618.        The character in the    low order byte of c is written to the
  619.        display using PC-DOS function 2.     Refer to appendix G of    the
  620.        BASIC manual to determine the effect of each possible character
  621.        code.  If the character passed is a carriage return, a line feed
  622.        is also sent to the display.  This function returns the character
  623.        passed to it.
  624.  
  625. More ?
  626.  
  627.        3.  Read    a line from the    keyboard.
  628.  
  629.                    gets(buffer);
  630.  
  631.        Reads one line of characters    into the character array buffer
  632.        using PC-DOS function 10    for buffered keyboard input.  Editing of
  633.        the buffer during character entry is supported by PC-DOS    (see
  634.        chapter 1 of the    DOS manual).  A    null character is placed at the
  635.        end of the line (replaces the usual carriage return at the end of
  636.        the line).  Note:  the buffer is    assumed    to be at least 80 bytes
  637.        in length.
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.                   - 10 -
  650. More ?
  651.  
  652.  
  653.  
  654.  
  655.        4.  Print a line    on the display.
  656.  
  657.                    puts(buffer);
  658.  
  659.        Each    character of the buffer    is written to the display using
  660.        PC-DOS function 2 (display character).  Refer to    appendix G of
  661.        the BASIC manual    to see how the character codes are interpreted.
  662.        Characters are sent to the display until    a null character is
  663.        encountered.  The null character    is not sent to the display.  No
  664.        carriage    return or line feed is automatically sent to the
  665.        display.
  666.  
  667.        5.  Open    a disk file for    processing.
  668.  
  669.                    ptr = fopen(name,mode);
  670.  
  671.        The named file is opened for    processing using DOS function
  672.        15.  The    name is    parsed using DOS function 41 before the    open
  673.        call.  The mode determines how the file is opened.  An "r" or "R"
  674.        opens it    for input and "w" or "W" opens it for output.  Notice
  675. More ?
  676.  
  677.        that mode is a pointer to a string.  The    string contains    the
  678.        character indicating the    desired    mode.  No error    checks are made.
  679.        The pointer returned is an offset into the library data segment
  680.        of an I/O structure.  The structure consists of the FCB followed
  681.        by the sector buffer (see CPCLIB    data segment).    This pointer
  682.        must be passed to functions getc, putc and fclose described
  683.        below.  If the open fails, a zero is returned to    ptr.  The open
  684.        can fail    for a variety of reasons.  No more than    four files may
  685.        be open at one time.  So    lack of    an available I/O structure can
  686.        cause failure.  The filename supplied could be in error or not
  687.        exist.  It could    be that    the mode indicated is not one of the
  688.        four possible characters    indicated above.  Programming note:  to
  689.        test if a file exists before opening it for output, first open it
  690.        for input.  If this open    is successful the file exists.
  691.  
  692.        6.  Close a disk    file.
  693.  
  694.                    fclose(ptr);
  695.  
  696.        The file described by the I/O structure indicated by    ptr is
  697.        closed to further processing.  Any unwritten characters in the
  698.        sector buffer are written to disk first.     No error check    is made
  699.        on the value in ptr.  The function returns a zero if the    close
  700. More ?
  701.  
  702.        fails.  It returns a non-zero value if the close    is successful.
  703.        Note that files are not automatically closed when the program
  704.        exits.
  705.  
  706.        7.  Read    the next character from    an opened disk file.
  707.  
  708.                    c = getc(ptr);
  709.  
  710.  
  711.  
  712.  
  713.  
  714.  
  715.  
  716.  
  717.  
  718.  
  719.  
  720.  
  721.                   - 11 -
  722.  
  723.  
  724.  
  725. More ?
  726.  
  727.        The next unread character is    returned.  The ptr is the I/O
  728.        structure offset    returned by fopen.  The    file is    assumed    to be a
  729.        text file.  When    a carriage return is read, the character that
  730.        immediately follows the carriage    return is presumed to be a line
  731.        feed and    is discarded automatically.  (No check is made to verify
  732.        that it was a line feed).  When a CTRL-Z    or a physical
  733.        end-of-file is detected,    a -1 is    returned.  A read error    also
  734.        returns a -1.
  735.  
  736.        8.  Write a character to    an opened disk file.
  737.  
  738.                    c = putc(c,ptr);
  739.  
  740.        The character is buffered into the sector buffer indicated by
  741.        the ptr (see fopen).  If    the character is a carriage return, a
  742.        line feed is automatically buffered.  A physical    disk write
  743.        occurs when the sector buffer is    filled.     This function returns
  744.        the argument character if no error occurs.  A -1    is returned if
  745.        an error    occurs.
  746.  
  747.        9.  Call    to PC-DOS.
  748.  
  749.                    ax =    pcdos(ah,dx);
  750. More ?
  751.  
  752.  
  753.        This    function calls PC-DOS.    The low    order byte of the first
  754.        argument    is placed into the AH register.     The second argument is
  755.        placed into the DX register.  PC-DOS returns a value in the AX
  756.        register.  This value is    stored into the    variable ax as
  757.        indicated.
  758.  
  759.        This    function is useful for supporting I/O to the printer or
  760.        communications device.  The following function sends the    passed
  761.        character to the    printer.
  762.  
  763.              listchar(c)
  764.               char c;
  765.              {
  766.               pcdos(5,c);
  767.               return (c);
  768.              }
  769.  
  770.  
  771.  
  772.  
  773.  
  774.  
  775. More ?
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.                   - 12 -
  794.  
  795.  
  796.  
  797.        THE SYSTEM INTERFACE LIBRARY ROUTINES
  798.  
  799.  
  800. More ?
  801.  
  802.        Like    those used above, the following    additional declarations
  803.        are made    to illustrate usage of the system interface library
  804.        routines.  These    routines generally provide access to the
  805.        hardware    on the PC or to    special    software elements of the system.
  806.  
  807.               int port,ah,al,bh,bl,ch,cl,dh,dl;
  808.               char string[256];
  809.               int val;
  810.  
  811.        Some    of the declared    names refer to 808x registers.    When the
  812.        name of an 8-bit    register appears as an argument    in the examples
  813.        below, the low order byte of the    value passed is    copied into the
  814.        808x register with the same name    to execute the function
  815.        indicated.  If a    16-bit register    is designated, the full    16-bit
  816.        argument    is loaded into the 808x    register with the same name.
  817.  
  818.        1.  Send    a byte to a physical output port.
  819.  
  820.                    out808x(port,al);
  821.  
  822.        The low order byte of the second argument is    sent to    the
  823.        hardware    port address indicated by the first argument.  No value
  824.        is returned.  Refer to the PC Technical Reference Manual    for a
  825. More ?
  826.  
  827.        description of the physical I/O ports on    the PC.
  828.  
  829.        2.  Input a byte    from a physical    input port.
  830.  
  831.                    val = in808x(port);
  832.  
  833.        An IN instruction is    executed using the hardware port address
  834.        provided    by the argument.  The byte read    is sign    extended and
  835.        returned    as a 16-bit value.  Refer to the PC Technical Reference
  836.        Manual for a description    of the physical    I/O ports on the PC.
  837.  
  838.        3.  Display control through the PC rom BIOS.
  839.  
  840.                 int10(ah,al,bh,bl,ch,cl,dh,dl);
  841.  
  842.        PC-DOS does not support complete display capabilities as
  843.        provided    on the PC.  This function allows the small-c programmer
  844.        control over the    display    as supported by    the rom    BIOS routines.
  845.        The PC Technical    Reference Manual contains a description    in the
  846.        rom listings of the required parameter values.  Certain functions
  847.        may not require all of the argument registers.  A dummy argument
  848.        must be provided, however, since    the library routine expects all
  849.        of the indicated    arguments (it is not function sensitive).
  850. More ?
  851.  
  852.  
  853.        4.  Control and I/O through the asynchronous port.
  854.  
  855.  
  856.  
  857.  
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.  
  865.                   - 13 -
  866.  
  867.  
  868.  
  869.                    ax = int14(ah,al,dx);
  870.  
  871.        Support of the async    adapter    through    PC-DOS is not complete
  872.        (especially on status information).  This function allows the
  873.        small-c programmer greater control over the comm    port.  Again,
  874.        the ROM listings    in the PC Technical Reference Manual contain a
  875. More ?
  876.  
  877.        complete    description of the parameters for this function.
  878.  
  879.        5.  Sound the bell.
  880.  
  881.                     bell();
  882.  
  883.        This    function simply    calls PC-DOS to    display    the bell
  884.        character code.
  885.  
  886.        6.  Clear the display buffer (and hence the display screen).
  887.  
  888.                    clrscreen();
  889.  
  890.        This    is essentially a clear screen function as provided on
  891.        many dumb terminals.  This function illustrates how the PC
  892.        programmer may manipulate the display memory directly to    manage
  893.        the display.
  894.  
  895.        7.  Copy    code segment prefix into a small-c data    array.
  896.  
  897.                  copyprefix(string);
  898.  
  899.        The program prefix as described in the DOS manual contains
  900. More ?
  901.  
  902.        information that    may be useful to the small-c programmer.  For an
  903.        example,    study the sample program provided on the distribution
  904.        disk.  This function copies all 256 bytes of the    prefix into
  905.        string.    Using appropriate offsets (or subscripts), the contents
  906.        of the prefix area can be examined.
  907.  
  908.        8.  Exit    to PC-DOS.
  909.  
  910.                      exit();
  911.  
  912.        This    is the function    to use in exiting a small-c program at a
  913.        point other than    a normal return    from the main()    function.  The
  914.        exit function assumes that the DS and SS    registers are unchanged
  915.        from their contents at program entry.
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925. More ?
  926.  
  927.  
  928.  
  929.  
  930.  
  931.  
  932.  
  933.  
  934.  
  935.  
  936.  
  937.                   - 14 -
  938.  
  939.  
  940.  
  941.        IV.  ASSEMBLY LANGUAGE INTERFACE
  942.  
  943.        Some    remaining portions of this manual are reproduced from
  944.        the user    manual for the small-c compiler    distributed by The Code
  945.        Works.  Interfacing to assembly language    is accomplished    in two
  946.        ways.  As the library routines demonstrate, you can simply code a
  947.        module in the code segment CSEG,    assemble it and    LINK will
  948.        resolve the call    if the function    name is    made PUBLIC.  You can
  949.        build your own assembly language    library    to LINK    with small-c
  950. More ?
  951.  
  952.        programs    that you write.
  953.  
  954.        The compiler    also supports a    language construct that    permits
  955.        in-line assembly    language code to be directly inserted into the
  956.        generated output    file.  This language construct is the
  957.        #asm...#endasm statements.  Like    all preprocessor commands, #asm
  958.        and #endasm must    be entered in lower case.  Since it is
  959.        considered by the compiler to be    a single statement, it may
  960.        appear any where    a statement is needed.    For example,
  961.  
  962.              while(...) #asm...#endasm
  963.  
  964.              or
  965.  
  966.              if(...) #asm...#endasm    else ...
  967.  
  968.        Due to the workings of the preprocessor (which must be
  969.        suppressed by this construct), the pseudo-op #asm must be the
  970.        last item before    the carriage return on the end of the line
  971.        (since the text between #asm and    the carriage return is thrown
  972.        away).  The parser is free-format (outside of these exceptions).
  973.        So the expected format is as follows:
  974.  
  975. More ?
  976.  
  977.                if (...)    #asm        [nothing following #asm]
  978.                    ...
  979.                    ...
  980.                    #endasm
  981.                else statement;
  982.  
  983.        A semicolon is not required after the #endasm.
  984.  
  985.        Assembly language code within the #asm...#endasm context can
  986.        access all global variables and functions by name.  It is up to
  987.        the programmer to know the data type of a variable (i.e.     whether
  988.        to access a byte    or a word).  Global variables should be    accessed
  989.        relative    to the stack segment as    opposed    to the data segment.  To
  990.        store the AX register into the variable named intvar, code
  991.  
  992.                    MOV SS:QZINTVAR,AX
  993.  
  994.        All global variables    and function names have    a 'QZ' prefix
  995.        added by    the compiler.  This is illustrated above.  As another
  996.  
  997.  
  998.  
  999.  
  1000. More ?
  1001.  
  1002.  
  1003.  
  1004.  
  1005.  
  1006.  
  1007.  
  1008.  
  1009.                   - 15 -
  1010.  
  1011.  
  1012.  
  1013.        illustration, to    call putchar() in an assembler routine,    code
  1014.        CALL QZPUTCHAR.    Since the library is not assembled with    the
  1015.        generated code, it is necessary to tell the assembler that a
  1016.        library name is external.  Insert the statement
  1017.  
  1018.                    EXTRN     QZPUTCHAR:NEAR
  1019.  
  1020.        in your assembly    language code.    If putchar() is    called by the
  1021.        small-c code containing your assembler code, then you do    not need
  1022.        to insert the EXTRN statement.  The compiler will generate one
  1023.        for the reference in the    small-c    code.  A similar situation
  1024.        exists for global data items.  For instance, if intvar is not
  1025. More ?
  1026.  
  1027.        defined (or referenced) by containing small-c code, it will be
  1028.        necessary to code
  1029.  
  1030.                    EXTRN QZINTVAR:NEAR
  1031.  
  1032.        For other illustrations of this,    refer to the generated code for
  1033.        the sample program on the distribution disk to see how the
  1034.        compiler    handles    similar    references.
  1035.  
  1036.        External assembly language routines invoked by function calls
  1037.        from the    small-c    code have access to all    registers.  However, the
  1038.        DS and SS (and naturally    CS) must be preserved across the
  1039.        assembly    language code.    All other registers can    be altered
  1040.        without restoration.  The calling program removes arguments from
  1041.        the stack upon return.  The function should not prune the stack
  1042.        itself.
  1043.  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050. More ?
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.  
  1064.  
  1065.  
  1066.  
  1067.  
  1068.  
  1069.  
  1070.  
  1071.  
  1072.  
  1073.  
  1074.  
  1075. More ?
  1076.  
  1077.  
  1078.  
  1079.  
  1080.  
  1081.                   - 16 -
  1082.  
  1083.  
  1084.  
  1085.        RUN TIME    CODE STRUCTURE AND SEGMENT USAGE
  1086.  
  1087.  
  1088.        The compiler    generates three    segments as a result of
  1089.        processing the user's small-c program.  Executable code is placed
  1090.        in segment CSEG with a class 'code'.  Data items    are stored in
  1091.        the segment STACK with the class    'stack'.  No information is
  1092.        stored in generated segment DUMMY.  It is produced to avoid a
  1093.        LINK error message.  The    run time library makes use of a    data
  1094.        segment DATASEG also in the class 'code'.  The LINK program
  1095.        combines    all output files with specified    libraries to produce the
  1096.        executable module.  This    module,    when loaded into memory, has the
  1097.        segments    in class 'code'    first followed by the stack segment
  1098.        whose class is 'stack'.    The entry point    is CCGO    in the run time
  1099.        library.     Routine CCGO loads the    stack segment register and sets
  1100. More ?
  1101.  
  1102.        the stack pointer SP to the highest possible value.  It pushes
  1103.        information necessary to    return to DOS onto the stack, then calls
  1104.        the user's main() function.  The    exit() routine is entered either
  1105.        by a call from the user program or upon a return    from main().
  1106.        The function exit() cleans the stack off    up to the information
  1107.        placed there by CCGO.  It then does a long return to DOS.
  1108.  
  1109.        During execution, the stack is used extensively.  Function
  1110.        arguments are placed onto the stack in their textual order (left
  1111.        to right).  This    is illustrated below by    the code generated for
  1112.        the following statement.
  1113.  
  1114.              function(x,y,z,());
  1115.  
  1116.              MOV     BX,SS:QZX
  1117.              PUSH     BX
  1118.              MOV     BX,SS:QZY
  1119.              PUSH     BX
  1120.              CALL     QZZ
  1121.              PUSH     BX
  1122.              CALL     QZFUNCTION
  1123.              POP     CX
  1124.              POP     CX
  1125. More ?
  1126.  
  1127.              POP     CX
  1128.  
  1129.        Notice that the compiler    generated code to clean    up the stack.
  1130.  
  1131.        Local variables are allocated onto the stack.  The current value
  1132.        of SP thus becomes their    address.  For example, inside a
  1133.        function, the statement:
  1134.  
  1135.                     int    k;
  1136.  
  1137.        generates the code PUSH CX to occupy two    bytes on the stack.
  1138.        References to the value k use the current value of SP.  If
  1139.        another value is    defined, such as:
  1140.  
  1141.  
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  1147.  
  1148.  
  1149.  
  1150. More ?
  1151.  
  1152.  
  1153.                   - 17 -
  1154.  
  1155.  
  1156.  
  1157.                  char array[3];
  1158.  
  1159.        the compiler would generate
  1160.  
  1161.                DEC     SP
  1162.                PUSH    CX
  1163.  
  1164.        to reserve three    bytes on the stack.  The offset    of array is the
  1165.        current value of    SP.  So    array[0] is at SP+0, array[1] at SP+1,
  1166.        array[2]    at SP+2, and k would now be at SP+3.  Thus, assembly
  1167.        language    code in    the statement #asm...#endasm cannot access local
  1168.        variables by name.  They    can be accessed    by knowing how many
  1169.        intervening bytes have been allocated between the declaration of
  1170.        the variable and    its use.  It is    worth noting that local
  1171.        declarations use    only as    much stack space as required, including
  1172.        an odd number of    bytes.    However, function arguments always
  1173.        consist of two bytes apiece.  If    a function argument is of type
  1174.        char (one byte),    the it is sign extended    to obtain a 2 byte value
  1175. More ?
  1176.  
  1177.        to push onto the    stack.
  1178.  
  1179.  
  1180.  
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.  
  1190.  
  1191.  
  1192.  
  1193.  
  1194.  
  1195.  
  1196.  
  1197.  
  1198.  
  1199.  
  1200. More ?
  1201.  
  1202.  
  1203.  
  1204.  
  1205.  
  1206.  
  1207.  
  1208.  
  1209.  
  1210.  
  1211.  
  1212.  
  1213.  
  1214.  
  1215.  
  1216.  
  1217.  
  1218.  
  1219.  
  1220.  
  1221.  
  1222.  
  1223.                   - 18 -
  1224.  
  1225. More ?
  1226.  
  1227.  
  1228.  
  1229.        Appendix    A:  Small-c:PC COMPILER    SPECIFICATION
  1230.  
  1231.        The compiler supports the following.
  1232.  
  1233.        1.  Data    type declarations can be:
  1234.  
  1235.             char            8-bits
  1236.             int            16-bits
  1237.             extern char        external 8-bits
  1238.             extern int        external 16-bits
  1239.             extern            external 16-bits
  1240.  
  1241.        A pointer to either of these types is declared by placing an
  1242.        asterisk    "*" before the pointer name.  A    pointer    is a 16-bit
  1243.        stack offset.
  1244.  
  1245.        2.  Arrays must be single dimension (vector) structures of type
  1246.        char or int.
  1247.  
  1248.        3.  Expressions:
  1249.         unary operators:
  1250. More ?
  1251.  
  1252.             "-"    minus
  1253.             "*"    indirection
  1254.             "&"    address    of scalar
  1255.             "++"    increment, either prefix or postfix
  1256.             "--"    decrement, either prefix or postfix
  1257.  
  1258.         binary operators:
  1259.             "+"    addition
  1260.             "-"    subtraction
  1261.             "*"    multiplication
  1262.             "/"    division
  1263.             "%"    mod, i.e. remainder from division
  1264.             "|"    inclusive or
  1265.             "^"    exclusive or
  1266.             "&"    logical    and
  1267.             "=="    test for equality
  1268.             "!="    test for inequality
  1269.             "<"    test for less than
  1270.             "<="    test for less or equal
  1271.             ">"    test for greater than
  1272.             ">="    test for greater or equal
  1273.             "<<"    arithmetic shift left
  1274.             ">>"    arithmetic shift right
  1275. More ?
  1276.  
  1277.             "="    assignment
  1278.  
  1279.          primaries:
  1280.             array[expression]
  1281.             function(arg1,...,argn)
  1282.             constants:
  1283.                 decimal    number
  1284.  
  1285.  
  1286.  
  1287.  
  1288.  
  1289.  
  1290.  
  1291.  
  1292.  
  1293.  
  1294.  
  1295.                   - 19 -
  1296.  
  1297.  
  1298.  
  1299.                 quoted string ("sample")
  1300. More ?
  1301.  
  1302.                 primed string ('a' or '10')
  1303.             local variable (or pointer)
  1304.             global (static)    variable (or pointer)
  1305.  
  1306.        4.  Program control:
  1307.  
  1308.             if(expression) statement;
  1309.             if(expression) statement;
  1310.                 else statement;
  1311.             while (expression) statement;
  1312.             break;
  1313.             continue;
  1314.             return;
  1315.             return expression;
  1316.             ; (null    statement)
  1317.             compound statement:
  1318.             {statement1; statement2;...;statementn;}
  1319.  
  1320.        5.  Pointers
  1321.  
  1322.             local and static pointers can contain the
  1323.        address of "char" or "int" data items.
  1324.  
  1325. More ?
  1326.  
  1327.        6.  Compiler commands:
  1328.  
  1329.         #define    name string
  1330.             (preprocessor will replace name    by string
  1331.        throughout the program text)
  1332.         #include filename
  1333.              (Input    is suspended from the input filename and
  1334.        text is read from the file named    in the include statement.  When
  1335.        end-of-file is detected,    input is resumed from the input
  1336.        filename.  A separate output file is not    created    for the    #include
  1337.        file.  Its output is directed to    the currently open output file.)
  1338.         #asm
  1339.              (see section IV for description)
  1340.  
  1341.        7.  Miscellaneous notes:
  1342.  
  1343.        Expression evaluation maintains the same    hierarchy as standard C.
  1344.  
  1345.        Function    calls are defined as any primary followed by an    open
  1346.        parenthesis.  Legal forms include:
  1347.  
  1348.              variable();
  1349.              array[expression]();
  1350. More ?
  1351.  
  1352.              constant();
  1353.              function() ();
  1354.  
  1355.        NOTE:  the various function call    forms are not supported    in
  1356.  
  1357.  
  1358.  
  1359.  
  1360.  
  1361.  
  1362.  
  1363.  
  1364.  
  1365.  
  1366.  
  1367.                   - 20 -
  1368.  
  1369.  
  1370.  
  1371.        standard    C.
  1372.  
  1373.        Pointer arithmetic takes    into account the data type the pointer
  1374.        was declared for    (e.g. ptr++ will increment by 2    if declared
  1375. More ?
  1376.  
  1377.        "int *ptr;").
  1378.  
  1379.        Pointers    are compared as    unsigned 16-bit    values.
  1380.  
  1381.        The generated code is pure.  Data is separated from executable
  1382.        code.
  1383.  
  1384.        The generated code is reentrant.     Since local variables are
  1385.        allocated on the    stack, each new    invocation of a    function
  1386.        generates a new copy of local variables.
  1387.  
  1388.  
  1389.  
  1390.  
  1391.  
  1392.  
  1393.  
  1394.  
  1395.  
  1396.  
  1397.  
  1398.  
  1399.  
  1400. More ?
  1401.  
  1402.  
  1403.  
  1404.  
  1405.  
  1406.  
  1407.  
  1408.  
  1409.  
  1410.  
  1411.  
  1412.  
  1413.  
  1414.  
  1415.  
  1416.  
  1417.  
  1418.  
  1419.  
  1420.  
  1421.  
  1422.  
  1423.  
  1424.  
  1425. More ?
  1426.  
  1427.  
  1428.  
  1429.  
  1430.  
  1431.  
  1432.  
  1433.  
  1434.  
  1435.  
  1436.  
  1437.  
  1438.  
  1439.                   - 21 -
  1440.  
  1441.  
  1442.  
  1443.        Appendix    B:  COMPILER RESTRICTIONS AND LIMITATIONS
  1444.  
  1445.        The compiler does not support:
  1446.  
  1447.        1.  Structures and unions
  1448.  
  1449.        2.  Multi-dimensional arrays
  1450. More ?
  1451.  
  1452.  
  1453.        3.  Floating point data
  1454.  
  1455.        4.  Long    integers
  1456.  
  1457.        5.  Functions that return anything but "int" values
  1458.  
  1459.        6.  Unary operators "!",    "~", "sizeof", casts
  1460.  
  1461.        7.  The operators "&&", "||", "?:", and ","
  1462.  
  1463.        8.  Assignment operators:
  1464.  
  1465.         +=, -=,    *=, /=,    %=, >>=, <<=, &=, ^=,
  1466.  
  1467. File Area #17: OTHER\
  1468. A)rea-Change F)iles T)ype M)ain-Menu 
  1469.  
  1470. File: A F T M or ? for help: 
  1471.  
  1472.  
  1473. File Area #17: OTHER\
  1474. A)rea-Change F)iles T)ype M)ain-Menu 
  1475.  
  1476. File: A F T M or ? for help: 
  1477.  
  1478.  
  1479. File Area #17: OTHER\
  1480. A)rea-Change F)iles T)ype M)ain-Menu 
  1481.  
  1482. File: A F T M or ? for help: