Quetzalcoatl Programmers' Manual.

 

Title:

Queztalcoatl 6502 C Compiler.

Abstract:

Some very brief notes for the ALPHA version.

Projects:

Queztalcoatl.

File:

UPL_UM03A.DOC

Date:

September 27, 1999 2:56 PM
(Only minor changes made since the September 21, 1998 11:38 PM version)

Author:

Brendan Jones.

Security:

UNCLASSIFIED.

THIS ALPHA VERSION IS FOR LIMITED DISTRIBUTION.

 

 

© Brendan Jones, 1998. All Rights Reserved.

This document contains confidential and proprietary information.

Do not distribute any part of this document without this cover page.

This document and its contents remain the intellectual property of Brendan Jones.

Patents may already be issued or pending for concepts expressed within this document.

This document may contain registered and unregistered trademark and servicemark names.

These are the property of their respective owners.

 

Legal Notice.

Before you use Queztalcoatl (the "Software") for the first time, please read this Disclaimer and License Agreement. By your action of using Queztalcoatl, you are agreeing to comply with all terms contained in this License.

LIMITATION OF LIABILITY: WE (BRENDAN JONES AND OUR AUTHORISED SUPPLIERS) OFFER NO WARRANTY OF ANY KIND EITHER EXPRESSED OR IMPLIED INCLUDING THOSE OF MERCHANTABILITY, NONINFRINGEMENT OF THIRD-PARTY INTELLECTUAL PROPERTY, OR FITNESS FOR A PARTICULAR PURPOSE. NEITHER WE NOR OUR AUTHORISED SUPPLIERS AND DISTRIBUTORS SHALL BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE OUR SOFTWARE, PRODUCTS OR SOFTWARE, EVEN IF WE OR OUR AUTHORISED SUPPLIERS AND DISTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THIS PRODUCT OR SERVICE MAY NOT BE USED IN JURISDICTIONS THAT PROHIBIT THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES.

The Title, ownership rights, and intellectual property rights in and to the Software shall remain with the Author. You agree to abide by the copyright law and all other applicable laws of The Commonwealth of Australia including, but not limited to, export control laws. You acknowledge that the Software in source code form remains a confidential trade secret of the Author therefore you agree not to modify the Software or attempt to decipher, decompile, disassemble or reverse engineer the Software, except to the extent applicable laws specifically prohibit such restriction.

This document contains trademark and servicemark names. These are the property of their respective owners.

References in this publication to products, programs, or services do not imply that Brendan Jones intends to make these available in all countries in which Brendan Jones operates.

This publication may contain examples of data and reports used in daily business operations. To illustrate them as completely as possible, the examples may include the names of individuals, companies, brands and products. All of these names are fictitious and any similarity to the names and addresses used by an actual business enterprise is entirely coincidental.

Brendan Jones welcomes comments on products and services including this software and documentation. Brendan Jones may use or distribute whatever information you supply in any way it believes appropriate without incurring any obligation to you.

Queztalcoatl is free for non-commercial use. It isn’t available for commercial use at this stage.

 

 

 

Table of Contents.

1. Introduction. *

2. Language. *

2.1 Identifiers. *

2.2 Types. *

2.2.1 Atomic Types. *

2.2.2 Enumerated Types. *

2.2.3 typedef. *

2.2.4 Unsupported. *

2.3 Variables. *

2.3.1 Modifiers. *

2.3.2 Arrays. *

2.4 Statements. *

2.4.1 Compound Statements. *

2.4.2 if Statement. *

2.4.3 while Statement *

2.4.4 do while Statement *

2.4.5 for Statement *

2.4.6 Assignment Statement. *

2.4.7 Increment Statement. *

2.4.8 Decrement Statement. *

2.4.9 call Statement *

2.4.10 return Statement *

2.4.11 Console I/O. *

2.4.12 Expressions. *

2.5 Subroutines. *

2.6 Program. *

2.7 Preprocessor. *

2.8 Compiling. *

  1. Introduction.
  2. Some quick notes I did for the Alpha release. Firstly the alpha software contains bugs and is largely untested; Don’t redistribute it or this documentation. Check http://www.kdef.com/geek/vic regularly for updates.

    Type this for general command line help:

    queztalcoatl --help

    Queztalcoatl isn’t C, even if it looks a lot like it. Queztalcoatl will never be brought up to ANSI level C. It’s a testbed for optimisation; not another C compiler – the world’s got enough of those. :-) E-mail flaming me because Queztalcoatl lacks full-blown C functionality will be rudely ignored and the sender’s e-mail address sold to spammers. :-)

    The runtime library is included; fully commented. Port away!

    Bug reports to quetzalcoatlbj@kdef.com.

  3. Language.
  4.  

    1. Identifiers.
    2. Identifiers are between 1 and 64 characters in length. They must consist of letters (upper and lower case), digits and the underscore character "_". They must begin with a letter. The case of the identifiers is significant. That is, "ZOO", "zoo" and "Zoo" are all different identifiers.

       

    3. Types.
      1. Atomic Types.
      2. The following types are supported:

        Type

        Range

        Description

        void

         

        Means "no type."

        byte

        0..255

        Unsigned byte. Prints as an unsigned number.

        char

        -128..127

        Character. Signed byte. Prints as a character.

        boolean

        -128..127

        Boolean (true -1 or false 0). Signed byte.

        Prints as a signed number.

        short

        -32,768..32,767

        Signed word. Prints as a signed number.

        ushort

        0..65,535

        Unsigned word. Prints as an unsigned number.

        int

         

        Same as short.

         

      3. Enumerated Types.
      4. Enumerated types are declared using Conventional C syntax. For example:

        enum cat

        {

        oscar,

        socks,

        p_cat,

        charlie,

        simba

        } my_cat, your_cat;

         

      5. typedef.
      6. typedef lets you effectively alias one type as another. For example:

        typedef int dollars;

        Alpha Release: Array types may not be aliased in this manner.

         

      7. Unsupported.

      Alpha Release: Structures and pointers may are not supported in the alpha release. (Structures may be declared, but they can’t actually be accessed!)

       

    4. Variables.
    5. Variables are declared and initialised using Conventional C syntax.

      int score = 0;

      boolean game_over;

      Unlike Conventional C, variables declared within subroutines cannot be initialised.

       

      1. Modifiers.
        1. const.
        2. Adding a const modifier to a declaration declares an assigned value as a constant. The constant exists purely as a compile-time constant. It is not allocated memory. This differs with Conventional C, where the const modifier only prevents a memory variable from being changed.

          const int dozen = 12;

          const int bakers_dozen = dozen + 1;

          The following constants are predefined.

          Constant

          Type

          Value

          true

          boolean

          -1

          false

          boolean

          0

          endl

          char

          ‘\n’ (The newline character; 10).

           

        3. static.
        4. Static variables are allocated dedicated memory for the duration of the program. Within a subroutine a static variable will maintain its last assigned value, even between calls or when the variable is out of scope. By default, all global variables have this static behaviour. Thus the static keyword only needs to be declared when the variable is being declared within a subroutine.

          static int points;

           

        5. auto.

        Automatic variables may only be declared within subroutines. They are allocated dynamic memory from the program stack. Subroutine with automatic variables may be called recursively. Each call has its own private automatic variables allocated. These may be used without affecting the values held by earlier calls. (cf. static variables).

        auto int points;

        In Conventional C using automatic variables is usually a good idea. On a 6502 however it’s not so simple. Automatic variables slower to access than static variables. How much slower depends on the implementation the compiler chooses. By limiting the amount of dynamic storage available on the program stack they can be made nearly as fast as static variables, but this approach limits the program stack to 256 bytes. Those 256 bytes must be shared between all automatic variables and parameters currently in existence (even for nested calls in progress to other subroutines) and temporary storage by the runtime library. That doesn’t leave a lot of room; Infact it’s very easy to use up all your memory very quickly and not even realise it. Even so, this is the approach Queztalcoatl uses. Why?

        The alternative approach is to allow for a large program stack. While that does let you have lots of automatic variables, it makes the code much larger and much slower. This approach usually isn’t practical, given that 6502 machines can have as little as a few kilobytes of memory to begin with.

        When using Queztalcoatl we recommend you keep the number of automatic variables to a minimum; Only use them if you need to do recursive calls. (Similarly you should keep the number of parameters and nested subroutine calls to a minimum too.) Never use an automatic variable where a static variable will do.

         

      2. Arrays.

      One dimensional arrays of any of the atomic types may be declared outside of subroutines. They may be initialised using Conventional C syntax. Character arrays may be initialised with strings.

      const int players = 10;

      int score[players];

      char name[] = "Tweetie Pie";

      int odds[4] = {1, 3, 5, 7}

      Unlike Conventional C, arrays may not be declared within subroutines.

       

    6. Statements.
    7.  

      1. Compound Statements.
      2. { { ( auto | static ) type { identifier # , } ) ; { statement } }

        Compound statements consist of a list of statements, enclosed in curly braces. Automatic and static variables may be declared at the start of the compound statement. Each statement in the list is terminated with a semicolon, unless the last part of that statement was itself another statement; This is identical to Conventional C.

        Unlike Conventional C, the auto and static keyword must be specified when declaring the type of variable. By default Conventional C defaults to automatic variables, but as discussed in Section 2.3.1.3 on Page * this is rarely the correct choice for Queztalcoatl. Thus we force you to explicitly choose the storage method for your variables.

         

      3. if Statement.
      4. if ( expression ) statement [ else statement ]

        If expression is true then the then statement is executed. If the expression is false and an else statement is provided then that will be executed instead.

        For example:

        if (weight >= 10) then cout << "Too heavy!";

         

      5. while Statement
      6. while ( expression ) statement

        The statement in the body are executed while expression remains true. The expression is tested before the statement is executed, so it will not be executed at all if the expression is initially false.

        For example:

        while (weight < 10)

        {

        cout << "Adding 1 kg of packing foam.\n";

        weight++;

        }

         

      7. do while Statement
      8. do { statement } while ( expression )

        The statements in the body are executed while expression remains true. The expression is tested after the statements are executed, so they’ll be executed at least once.

         

      9. for Statement
      10. for ( assignment-statement ; expression ; increment-statement ) statement

        for ( assignment-statement ; expression ; decrement-statement ) statement

        The for statement is used to iterate a variable over a range of values, repeatedly executing statement. When execution begins the assignment-statement is executed. The loop then begins. The expression is evaluated, and if it is false we break out of the loop. Otherwise the statement and then the decrement-statement are executed. The loop then repeats.

        For example:

        for (i=0; i<10; i++)

        cout << i << endl;

        Alpha Release: Compared to Conventional C, this implementation of the for statement is inflexible. In Conventional C you can offer any expression as the assignment-statement and increment or decrement-statement.

         

      11. Assignment Statement.
      12. variable = expression

         

        1. Memory Assignment.

        You can examine and modify memory values directly.

         

         

        The predefined memory array lets you peek and poke memory.

        memory[650] = 255;

        fred = memory[4096];

      13. Increment Statement.
      14. variable++

        ++variable

        This statement increments (adds one to) the integer value of a variable. Incrementing the maximum value of a variable will result in it wrapping around to the minimum value.

        Alpha Release: Unlike Conventional C you may not include the increment statement within expressions.

         

      15. Decrement Statement.
      16. --variable

        variable--

        This statement decrements (subtracts one from) the integer value of a variable. Decrementing the minimum value of a variable will result in it wrapping around to the maximum value.

        Alpha Release: Unlike Conventional C you may not include the increment statement within expressions.

         

      17. call Statement
      18. call expression [ with reg [ in ] [ out ] ]

        If with reg is specified then the value of the variables a, x, y and p (if defined) is copied into and out of the corresponding 6502 registers before the call is made.

         

      19. return Statement
      20. return [ expression ]

        This statement is used to return from a function with the value expression.

         

      21. Console I/O.
      22.  

        1. Output.
        2. cout { << ( expression | string ) }

          put ( { ( expression | string ) # , } )

          putln [ ( { ( expression | string ) # , } ) ]

          You can force a character to be printed as a number by casting it.

          cout << (ushort)char

           

        3. Input
        4. char getch(void)

           

        5. Control

        ioctl (cin, ioctl_set, (ioctl_cooked | ioctl_raw_wait | ioctl_raw_nowait) )

        Cooked mode lets the user edit the line and press enter before returning the next character.

        Raw wait waits for them to press a key.

        Raw nowait returns immediately with 0 if no key is pressed.

         

      23. Expressions.
      24. and or * / % + - <= < == != > >=

        not –

         

        1. Casting.

      (new-type)expression

      eg. char ch = (char)65

       

    8. Subroutines.
    9. [ static ] type identifier ( { type identifier # , } ) ( compound-statement | ; )

      eg.

      void main(void)

      {

      cout << "HELLO WORLD!\n";

      }

      // Forward/external declaration

      void clear_screen(byte Color);

      int max(int A, int B)

      {

      if (A > B)

      return A;

      else

      return B;

      }

       

    10. Program.
    11. { subroutine-declaration | type-declaration | variable-declaration }

      Any order… Main subroutine is: void main(void)

       

    12. Preprocessor.
    13. #define identifier value


      #include "graphics.h"

      Not a real preprocessor; it just fakes it. Means you can’t eg. include just the middle of a subroutine from an include file… but then again… why would you want to? :-)

       

    14. Compiling.

hello.c

void main(void)

{

cout << "HELLO WORLD!\n";

}

To compile:

queztalcoatl –b hello.c

This will produce hello.bin.

The –b option tells Queztalcoatl to create a one-time BASIC bootstrap. (So you can run the program without having to remember the entry address; You can just type RUN).

To run in start eg. PCVIC, load the file and from BASIC type RUN.

Queztalcoatl has many options.

queztalcoatl --help

Remember you can have multiple files.

queztalcoatl –b hello.c graphics.c sound.c

To forcibly compile a certain runtime library (cf. the default generic library).

queztalcoatl –b hello.c graphics.c sound.c uplrlynx.asm

To use that runtime library:

queztalcoatl –b –r lynx hello.c graphics.c sound.c

 

BTW you can use Queztalcoatl as a regular assembler too.

End.