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