1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2024-11-16 08:04:37 +00:00

Added C02 documentation files doc/*

This commit is contained in:
Curtis F Kaylor 2018-01-28 14:00:23 -05:00
parent 203c55db4d
commit 7d770f1218
21 changed files with 2248 additions and 0 deletions

0
doc/assembler.txt Normal file
View File

BIN
doc/assemblers.ods Normal file

Binary file not shown.

170
doc/block.txt Normal file
View File

@ -0,0 +1,170 @@
Block Memory Functions
This library contains functions for accessing data in blocks of memory.
A block consists of up to 65,535 contiguous bytes. This allows for the
storage, retrieval, and manipulation of data exceeding the maximum
array length of 255.
These functions assume that a block is divided into equally sized segments
of up to 255 bytes in length. Data in the block is accessed by copying
data into and out of arrays with the same length as the segment size.
A segment consists of a string field, which is used as a key, followed
by a number of individual bytes. For example, the segments in a variable
table might be 9 bytes long, consisting of a 7 byte variable name string
(6 characters plus a terminator), the variable type (at index 7) and
the variable length (at index 8).
Usage: at the beginning of the program use the directives
#include <memory.h02>
#include <string.h02>
#include <block.h02>
The following application functions are defined:
blkbgn(&b); Block Begin: Set beginning of block to address b.
The beginning of a block is the first byte of memory
in the block.
Although a block usually begins on a 256 byte
boundary, this is not required.
Note: Sets variables blkslo and blkshi.
blkend(&e); Block End: Set end of block to address b. The end of
a block is the byte after the last byte of memory in
the block.
Although a block usually begins on a 256 byte
boundary, this is not required.
Note: Sets variables blkslo and blkshi.
blkseg(n); Block Segment: Set block segment size to n.
Required before calls any calls that manipulate
block segments.
Note: Sets blklen to n.
blkset(c); Block Set: Fill entire block with character c,
leaving block pointer at end of block.
Used to initialize a block before use.
blkrst(); Block Reset: Set block segment pointer to block
begin address.
This routine is called before populating a block with
calls to the blkapd function.
blknxt(); Block Next: Move block pointer forward by the segment
length set by a prior blkseg call.
If the block pointer is moved past the end of the
block, a value of 0 (false) is returned. Otherwise,
a value of 255 (true) is returned.
blkput(n ,&m); Block Append: Copy n bytes of array m to block
at current pointer location, and moves block pointer
forward by the segment length set by a prior blkseg
call.
If the appended bytes would overflow the end of the
block, no bytes are copied and a value of 0 (false)
is returned. Otherwise, the bytes are copied and
a value of 255 (true) is returned.
Note: Sets dstlo and dsthi to the block pointer prior
to the copy, updates blkslo and blkshi, then calls
the memcpy function.
blkget(n ,&m); Block Get: Copy n bytes from block at current
pointer location to array m, and moves block pointer
forward by the segment length set by a prior blkseg
call.
If the copied bytes would overflow the end of the
block, no bytes are copied and a value of 0 (false)
is returned. Otherwise, the bytes are copied and
a value of 255 (true) is returned.
Note: Sets dstlo and dsthi to the address of m,
srclo and srchi to the block pointer prior to the
copy, updates blkslo and blkshi, then calls the
memcpy function.
blkmem(n ,&m); Block Memory search: Search block for n byte long
segment matching array m.
If a matching segment is found, the value 255 (true)
is returned and the destination pointer is set to the
address of the matching segment, allowing it to be
overwritten with a subsequent memcpy call. Otherwise,
the value 0 (false) is returned.
Note: Sets srclo and srchi to the address of m,
dstlo and dsthi to the address of the matching segment,
and temp0 to n. Does not change the block pointer.
blkstr(n ,&s); Block String Search: Search block for n byte long
segments beginning with string s.
If a matching segment is found, the value 255 (true)
is returned and the segment is copied to the array set
by a prior memdst call. Otherwise, the value 0 (false)
is returned.
Note: Sets srclo and srchi to the address of the
segment, temp0 to n, and copies dstlo and dsthi to
temp1 and temp2. Does not change the block pointer.
blkswp(n); Block Swap: Swaps n bytes of array m with the current
block segment (pointed to by the block pointer. The
block pointer is not changed.
Requires a prior call to the memdst function specifying
an array at least n bytes long, which is used for
temporary storage.
Note: Sets temp0 to n, copies blklo and blkhi to dstlo,
and dsthi, and calls memswp.
blksrt(&m); Block Sort: Sort segments in block by initial string,
using array m as temporary storage.
Segments are sorted in alphabetical order, with segment
length set by a prior blkseg call, and sorting stops at
the first segment that begins with an empty string (the
first byte is 0), leaving the block pointer at that
segment.
Note: Uses the selection sort algorithm. Sets temp1
and temp2 to the address of array m.
Note: This library expects the following functions to be defined
setdst(&s); Set destination string pointer
setsrc(&s); Set source string pointer and initialize index
memcmp Compare memory
memcpy Copy memory
memsrc Set memory source and count
strcml Compare string (alternate entry point)
along with the zero page variable pairs
srclo, srchi Source String Pointer
dstlo, dsthi Destination String Pointer
blklo, blkhi Block Pointer
the static variable
blkslo, blkshi Block Start Address
blkelo, blkehi Block End Address
blklen Block Segment Length
as well as the transient variables
temp0, temp1, temp2 Temporary storage

628
doc/c02.txt Normal file
View File

@ -0,0 +1,628 @@
INTRODUCTION
C02 is a simple C-syntax language designed to generate highly optimized
code for the 6502 microprocessor. The C02 specification is a highly
specific subset of the C standard with some modifications and extensions
PURPOSE
Why create a whole new language, particularly one with severe restrictions,
when there are already full-featured C compilers available? It can be
argued that standard C is a poor fit for processors like the 6502. The C
was language designed to translate directly to machine language instructions
whenever possible. This works well on 32-bit processors, but requires either
a byte-code interpreter or the generation of complex code on a typical
8-bit processor. C02, on the other hand, has been designed to translate
directly to 6502 machine language instructions.
The C02 language and compiler were designed with two goals in mind.
The first goal is the ability to target machines with low memory: a few
kilobytes of RAM (assuming the generated object code is to be loaded into
and ran from RAM), or as little as 128 bytes of RAM and 2 kilobytes of ROM
(assuming the object code is to be run from a ROM or PROM).
The compiler is agnostic with regard to system calls and library functions.
Calculations and comparisons are done with 8 bit precision. Intermediate
results, array indexing, and function calls use the 6502 internal registers.
While this results in compiled code with virtually no overhead, it severely
restricts the syntax of the language.
The second goal is to port the compiler to C02 code so that it may be
compiled by itself and run on any 6502 based machine with sufficient memory
and appropriate peripherals. This slightly restricts the implementation of
code structures.
SOURCE AND OUTPUT FILES
C02 source code files are denoted with the .c02 extension. The compiler
reads the source code file, processes it, and generates an assembly
language file with the same name as the source code file, but with
the .asm extension instead of the .c02 extension. This assembly language
file is then assembled to create the final object code file.
Note: The default implementation of the compiler creates assembly
language code formatted for the DASM assembler. The generation of the
assembly language is parameterized, so it may be easily changed to
work with other assemblers.
COMMENTS
The parser recognizes both C style and C++ style comments.
C style comments begin with /* and end at next */. Nested C style comments
are not supported.
C++ style comments begin with // and end at the next newline. C++ style
comments my be nested inside C style comments.
DIRECTIVES
Directives are special instructions to the compiler. They do not directy
generate compiled code. A directive is denoted by a leading # character.
C02 currently supports only one directive.
The #include directive causes the compiler to read and process and external
file. In most cases, #include directives will be used with libraries of
function calls, but they can also be used to modularize the code that makes
up a program.
An #include directive is followed by the file name to be included. This
file name may be surrounded with either a < and > character, or by two "
characters. In the former case, the compiler looks for the file in an
implementation specific library directory (the default being ./include),
while in the latter case, the compiler looks for the file in the current
working directory. Two file types are currently supported.
Header files are denoted by the .h02 extension. A header file is used to
provide the compiler with the information necessary to use machine
language system and/or library routines written in assembly language,
and consists of comments and declarations. The declarations in a header
file added to the symbol table, but do not directly generate code. After
a header file has been processed, the compiler reads and process a
assembly language file with the same name as the header file, but with
the .a02 extension instead of the .h02 extension.
The compiler does not currently generate any assembler required
pseudo-operators, such as the specification of the target processor,
or the starting address of the assembled object code. Therefore, at least
one header file, with an accompanying assembly language file is needed
in order to successfully assemble the compiler generated code. Details
on the structure and implementation of a typical header file can be
found in the file header.txt.
Assembly language files are denoted by the .asm extension. When the
compiler processes an assembly language file, it simply inserts the contents
of the file into the generated code.
Note: Unlike standard C and C++, which use a preprocessor to process
directives, the C02 compiler processes directives directly.
CONSTANTS
A constant represents a value between 0 and 255. Values may be written as
a number (binary, decimal, osir hexadecimal) or a character literal.
A binary number consists of a % followed by eight binary digits (0 or 1).
A decimal number consists of one to three decimal digits (0 through 9).
A hexadecimal number consists of a $ followed by two hexadecimal digits
(0 throuth 9 or A through F).
A character literals consists of a single character surrounded by ' symbols.
A ' character may be specified by escaping it with a \.
Examples:
&0101010 Binary Number
123 Decimal Number
$FF Hexadecimal Number
'A' Character Literal
'\'' Escaped Character Literal
STRINGS
A string is a consecutive series of characters terminated by an ASCII null
character (a byte with the value 0).
A string literal is written as up to 255 printable characters. prefixed and
suffixed with " characters.
SYMBOLS
A symbol consists of an alphabetic character followed by zero to five
alphanumeric characters. Four types of symbols are supported: labels,
simple variables, variable arrays, and functions.
A label specifies a target point for a goto statement. A label is written
as a symbol suffixed by a : character.
A simple variable represents a single byte of memory. A variable is written
as a symbol without a suffix.
A variable array represents a block of up to 256 continuous bytes in
memory. An Array reference are written as a symbol suffixed a [ character,
index, and ] character. The lowest index of an array is 0, and the highest
index is one less than the number of bytes in the array. There is no bounds
checking on arrays: referencing an element beyond the end of the array will
access indeterminate memory locations.
A function is a subroutine that receives multiple values as arguments and
optionally returns a value. A function is written as a symbol suffixed with
a ( character, up to three arguments separated by commas, and a ) character,
The special symbols A, X, and Y represent the 6502 registers with the same
names. Registers may only be used in specific circumstances (which are
detailed in the following text). Various C02 statements modify registers
as they are processed, care should be taken when using them. However, when
used properly, register references can increase the efficiency of compiled
code.
STATEMENTS
Statements include declarations, assignments, stand-alone function calls,
and control structures. Most statements are suffixed with ; characters,
but some may be followed with program blocks.
BLOCKS
A program block is a series of statements surrounded by the { and }
characters. They may only be used with function definitions and control
structures.
DECLARATIONS
A declaration statement consists of type keyword (char or void) followed
by one or more variable names and optional definitions, or a single
function name and optional function block.
Variables may only be of type char and all variable declaration statements
are suffixed with a ; character.
A simple variable declaration may include an initial value definition in
the form of an = character and constant after the variable name.
A variable array may be declares in one of two ways: the variable name
suffixed with a [ character, a constant specifying the upper bound of
the array, and a ] character; or a variable name followed by an = character
and string literal or series of constants separated by , characters and
surrounded by { or } characters.
Variables are initialized at compile time. If a variable is changed during
execution, it will not be reinitialized unless the compiled program is
reloaded into memory.
Examples:
char c; //Defines variable c
char i, j; //Defines variables i and j
char r[7]; //Defines 8 byte array r
char s = "string"; //Defines 7 byte array s initialized to "string"
char m = {1,2,3}; //Defines 3 byte array m initialized to 1, 2, and 3
A function declaration consists of the function name suffixed with a (
character, followed zero to three comma separated simple variables and
a ) character. A function declaration terminated with a ; character is
called a forward declaration and does not generate any code, while one
followed by a program block creates the specified function. Functions of
type char explicitly return a value (using a return statement), while
functions of type void do not.
Examples:
void myfunc(); //Forward declaration of function myfunc
char min(tmp1, tmp2) {if (tmp1 < tmp2) return tmp1; else return tmp2;}
Note: Like all variables, function parameters are global. They must be
declared prior to the function decaration, and retain there values after
the function call. Although functions may be called recursively, they are
not re-entrant. Allocation of variables and functions is implementation
dependent, they could be placed in any part of memory and in any order.
The default behavior is to place variables directly after the program code,
including them as part of the generated object file.
The return value of a function is passed through the A register. A return
statement with an explicit expression will simply process that expression
(which leaves the result in the A register) before returning. A return
statement without an expression (including an implicit return) will, by
default, return the value of the last processed expression.
EXPRESSIONS
An expression is a sseries of one or more terms separated by operators.
The first term in an expression may be a function call, subscripted array
element, simple variable, constant, or register (A, X, or Y). An expression
may be preceded with a - character, in which case the first term is assumed
to be the constant 0.
Additional terms are limited to subscripted array elements, simple variables
and constants.
Operators:
+ — Add the following value.
- — Subtract the following value.
& — Bitwise AND with the following value.
| — Bitwise OR with the following value.
^ — Bitwise Exclusive OR with the following value.
Arithmetic operators have no precedence. All operations are performed in
left to right order. Expressions may not contain parenthesis.
Note: the character ! may be substituted for | on systems that do not
support the latter character. No escaping is necessary because a ! may
not appear anywere a | would.
After an expression has been evaluated, the A register will contain the
result.
EVALUATIONS
An evaluation is a construct which generates either TRUE or FALSE condition.
It may be an expression, a comparison, or a test.
A stand-alone expression evaluates to TRUE if the result is non-zero, or
FALSE if the result is zero.
A comparison consists of an expression, a comparator, and a term (subscripted
array element, simple variable, or constant).
Comparators:
= — Evaluates to TRUE if expression is equal to term
< — Evaluates to TRUE if expression is less than term
<= — Evaluates to TRUE if expression is less than or equal to term
> — Evaluates to TRUE if expression is greater than term
>= — Evaluates to TRUE if expression is greater than or equal to term
<> — Evaluates to TRUE if expression is not equal to term
The parser considers == equivalent to a single =. The operator <>
was chosen instead of the usual != because it simplified the parser design.
A test consists of an expression followed by a test-op.
Test-Ops:
:+ — Evaluates to TRUE if the result of the expression is positive
:- — Evaluates to TRUE if the result of the expression is negative
A negative value is one in which the high bit is a 1 (128 — 255), while a
positive value is one in which the high bit is a 0 (0 — 127). The primary
purpose of test operators is to check the results of functions that return
a positive value upon succesful completion and a negative value if an error
was encounters. They compile into smaller code than would be generated
using the equivalent comparison operators.
A comparison may be preceded by negation operator (a ! character), which
reverses the meaning of the entire comparison. For example,
! expr
evaluates to TRUE if expr is zero, or FALSE if it is non-zero; while
! expr = term
evaluates to TRUE if expr and term are not equal, or FALSE if they are; and
! expr :+
evaluates to TRUE if expr is negative, or FALSE if it is positive
Note: Evaluations are compiled directly into 6502 conditional branch
instructions, which precludes their use inside expressions. Standalone
expressions and test-ops generate a single branch instruction, and
therefore result in the most efficient code. Comparisons generate a
compare instruction and one or two branch instructions (=. <. >=, and <>
generate one, while <= and > generate two). A preceding negation operator
will switch the number of branch instructions used in a comparison, but
otherwise does not change the size of the generated code.
ARRAY SUBSCRIPTS
Individual elements of an array are accessed using subscript notation.
Subscripted array elements may be used as a terms in an expression, as well
as the target variable in an assignments. They are written as the variable
name suffixed with a [ character, followed by an index, and the ] character.
The index may be a constant, a simple variable, or a register (A, X or Y).
Examples:
z = r[i]; //Store the value from element i of array r into variable z
r[0] = z; //Store the value of variable z into the first element of r
Note: After a subscripted array reference, the 6502 X register will contain
the value of the index (unless the register Y was used as the index, in
which X register is not changed).
FUNCTION CALLS
A function call may be used as a stand-alone statement, or as the first
term in an expression. A function call consists of the function name
appended with a ( character, followed by zero to three arguments separated
with commas, and a closing ) character.
The first argument of a function call may be an expression, address, or
string (see below).
The second argument may be a term (subscripted array element, simple
variable, or constant), address, or string,
The third argument may only be a simple variable or constant.
If the first or second argument is an address or string, then no more
arguments may be passed.
To pass the address of a variable or array into a function, precede the
variable name with the address-of operator &. To pass a string, simply
specify the string as the argument.
Examples:
c = getchr(); //Get character from keyboard
n = abs(b+c-d); //Return the absolute value of result of expression
m = min(r[i], r[j]); //Return lesser of to array elements
l = strlen(&s); //Return the length of string s
p = strchr(c, &s); //Return position of character c in string s
putstr("Hello World"); //Write "Hello World" to screen
Note: This particular argument passing convention has been chosen because
of the 6502's limited number of registers and stack processing instructions.
When an address is passed, the high byte is stored in the Y register and
the low byte in the X register. If a string is passed, it is turned into
anonymous array, and it's address is passed in the Y and X registers.
Otherwise, the first argument is passed in the A register, the second in
the Y register, and the third in the X register.
EXTENDED PARAMETER PASSING
To enable direct calling of machine language routines that that do not match
the built-in parameter passing convention, C02 supports the non-standard
statements push, pop, and inline.
The push statement is used to push arguments onto the machine stack prior
to a function call. When using a push statement, it is followed by one or
more arguments, separated by commas, and terminated with a semi-colon. An
argument may be an expression, in which case the single byte result is
pushed onto the stack, or it may be an address or string, in which case the
address is pushed onto the string, high byte first and low byte second.
The pop statement is likewise used to pop arguments off of the machine
stack after a function call. When using a pop statement, it is followed
with one or more simple variables, separated by commas, and terminated
with a semicolon. If any of the arguments are to be discarded, an asterisk
can be specified instead of a variable name.
The number of arguments pushed and popped may or may not be the same,
depending on how the machine language routine manipulates the stack pointer.
Examples:
push d,r; mult(); pop p;
push x1,y1,x2,y2; rect(); pop *,*,*,*;
push &s, "tail"; strcat();
Note: The push and pop statements could also be used to manipulate the
stack inside or separate from a function, but this should be done with
care.
The inline statement is used when calling machine language routines that
expect constant byte or word values immediately following the 6502 JSR
instruction. A routine of this type will adjust the return address to the
point directly after the last instruction. When using the inline statement,
it is followed by one or more arguments, separated by commas, and
terminated with a semicolon. The arguments may be constants, addresses,
or strings.
Examples;
iprint(); inline "Hello World"; //Print "Hello World"
irect(); inline 10,10,100,100; //Draw rectangle from (10,10) to (100,100)
Note: If a string is specified in an inline statement, rather than creating
an anonymous string and compiling the address inline, the entire string will
be compiled directly inline.
ASSIGNMENTS
An assignment is a statement in which the result of an expression is stored
in a variable. An assignment usually consists of a simple variable or
subscripted array element, an = character, and an expression, terminated
with a ; character.
Examples:
i = i + 1; //Add 1 to contents variable i
c = getchr(); //Call function and store result in variable c
s[i] = 0; //Terminate string at position i
SHORTCUT-IFS
A shortcut-if is a special form of assignment consisting of an evaluation
and two expressions, of which one will be assigned based on the result
of the evaluation. A shortcut-if is written as a condition surrounded
by ( and ) characters, followed by a ? character, the expression to be
evaluated if the condition was true, a : character, and the expression to
be evaluated if the condition was false.
Example:
result = (value1 < value) ? value1 : value2;
Note: Shortcut-ifs may only be used with assignments. This may change in
the future.
POST-OPERATORS
A post-operator is a special form of assignment which modifies the value
of a variable. The post-operator is suffixed to the variable it modifies.
Post-Operators:
++ Increment variable (increase it's value by 1)
-- Decrement variable (decrease it's value by 1)
<< Left shift variable
>> Right shift variable
Post-operators may be used with either simple variables or subscripted
array elements.
Examples:
i++; //Increment the contents variable i
b[i]<<; //Left shift the contenta of element i of array b
Note: Post-operators may only be used in stand-alone statements, although
this may change in the future.
ASSIGNMENTS TO REGISTERS
Registers A, X, and Y may assigned to using the = character. Register A
(but not X or Y) may be used with the << and >> post-operators, while
registers X and Y (but not A) may be used with the ++ and -- post-operators.
IMPLICIT ASSIGNMENTS
A statement consisting of only a simple variable is treated as an
implicit assignment of the A register to the variable in question.
This is useful on systems that use memory locations as strobe registers.
Examples:
HMOVE; //Move Objects (Atari VCS)
S80VID; //Enable 80-Column Video (Apple II)
Note: An implicit assignment generates an STA opcode with the variable
as the operand.
GOTO STATEMENT
A goto statement unconditionally transfers program execution to the
specified label. When using a goto statement, it is followed by the
label name and a terminating semicolon.
Example:
goto end;
Note: A goto statement may be executed from within a loop structure
(although a break or continue statement is preferred), but should not
normally be used to jump from inside a function to outside of it, as
this would leave the return address on the machine stack.
IF AND ELSE STATEMENTS
The if then and else statements are used to conditionally execute blocks
of code.
When using the if keyword, it is followed by an evaluation (surrounded by
parenthesis) and the block of code to be executed if the evaluation was true.
An else statement may directly follow an if statement (with no other
executable code intervening). The else keyword is followed by the block
of code to be executed if the evaluation was false.
Examples:
if (c = 27) goto end;
if (n) q = (n/d) else putstr("Division by 0!");
if (r[j]<r[i]) {t=r[i],r[i]=r[j],r[j]=t)}
Note: In order to optimize the compiled code, the if and else statements
are to 6502 relative branch instructions. This limits the amount of
generated code between the if statement and the end of the if/else block
to slightly less than 127 characters. This should be sufficient in most
cases, but larger code blocks can be accomodated using function calls or
goto statements.
WHILE LOOPS
The while statement is used to conditionally execute code in a loop. When
using the while keyword, it is followed by an evalution (surrounded by
parenthesis) and the the block of code to be executed while the evaluation
is true. If the evaluation is false when the while statement is entered,
the code in the block will never be executed.
Alternatively, the while keyword may be followed by a pair of empty
parenthesis, in which case an evaluation of true is implied.
Examples:
c = 'A' ; while (c <= 'Z') {putchr(c); c++;} //Print letters A-Z
while() if (rdkey()) break; //Wait for a keypress
Note: While loops are compiled using the 6502 JMP statements, so the code
blocks may be abritrarily large.
DO WHILE LOOPS
The do statement used with to conditionally execute code in a loop at
least once. When using the do keyword, it is followed by the block of
code to be executed, a while statement, an evaluation (surrounded
by parenthesis), and a terminating semicolon.
A while statement that follows a do loop must contain an evaluation.
The while statement is evaluated after each iteration of the loop, and
if it is true, the code block is repeated.
Examples:
do c = rdkey(); while (c=0); //Wait for keypress
do (c = getchr(); putchr(c); while (c<>13) //Echo line to screen
Note: Unlike the other loop structures do/while statements do not use
6502 JMP instructions. This optimizes the compiled code, but limits
the amount of code inside the loop.
FOR LOOPS
The for statement allows the initialization, evaluation, and modification
of a loop condition in one place. For statements are usually used to
execute a piece of code a specific number of times, or to iterate through
a set of values.
When using the if keyword, it is followed by a pair of parenthesis
containing an initialization assignment statement (which is executed once),
a semicolon separator, an evaluation (which determines if the code block
is exectued), another semicolon separator, and an increment assignment
(which is executed after each iteration of the code block). This is then
followed by the block of code to be conditionally executed.
The assignments and conditional of a for loop must be populated. If an
infinite loop is desired, use a while () statement.
Examples:
for (c='A'; c<='Z'; c++) putchr(c); //Print letters A-Z
for (i=strlen(s)-1;i:+;i--) putchr(s[i]); //Print string s backwards
for (i=0;c>0;i++) {c=getchr();s[i]=c} //Read characters into string s
Note: For loops are compiled using the 6502 JMP statements, so the code
blocks may be abritrarily large. A for loop generates less efficient code
more than a simple while loop, but will always execute the increment
assignment on a continue.
BREAK AND CONTINUE
The break and continue statements are used to jump to the beginning or
end of a do, for, or while loop. Neither may be used outside of a loop.
When a break statement is encountered, program execution is transferred
to the statement immediately following the end of the block associated
with the innermost for or while loop. When using the break keyword, it is
followed with a trailing semicolon.
When a continue statement is encountered, program execution is transferred
to the beginning of the block associated with the innermost for or while
loop. In the case of a for statement, the increment assignment is executed,
followed by the evaluation, and in the case of a while statement, the
evaluation is executed. When using the break keyword, it is followed with
a trailing semicolon.
Examples:
do {c=rdkey(); if (c=0) continue; if (c=27) break;} while (c<>13);`
for (i=0;i<strlen(s);i++) {if (s[i]=0) break; putchr(s[i]);}
while() {c=rdkey;if (c=0) continue;putchr(c);if (c=13) break;}
Note: The break and continue statements may not be used inside a do/while\
loop. This may change in the future.
UNIMPLEMENTED FEATURES
The #define directive is recognized but generates an error. The exact
implementation of this directive has not yet been determined, so it has
been reserved for future use.
The #pragma directive is currently unrecognized. It may be implemented in
the future to allow the specification of assembler specific instructions.
The only type recognized by the compiler is char. Since the 6502 is an
8-bit processor, multi-byte types would generate over-complicated code.
For this reason, pointers are not currently implemented, athough the
address of operator can be used with specific statements. In addition,
the signed and unsigned keywords are unrecognized, due to the 6502's
limited signed comparison functionality.
The switch and case keywords are recognized, but generate an error. There
are no plans to implement these keywords. Due to single pass nature of the
compiler, the code generated by a switch/case structure would be no more
efficient than an equivalent series of if/then/else statements.

30
doc/c02vsC.txt Normal file
View File

@ -0,0 +1,30 @@
C02 for C programmers
TYPES
C02 only supports one data type: unsigned char.
POINTERS
C02 does not support pointer type variables or parameters. However, the
address-of operator may be used in function calls.
DECLARATIONS
Variable and function names may be no more than six characters in length.
Multiple variable declarations separated by commas are allowed.
A variable in a declaration may be initialized by following it with an
equal sign and a constant, however this declaration is done at compile
time, so no re-initialization will occur during code execution.
Array declarations using bracket syntax specify the upper bound, rather
than the array size. Therefore, the array will be allocated with one more
element than the specified number.
EXPRESSIONS
C02 supports the addition, subtraction, bitwise-and, bitwise-or, and
exclusive-or operators. The multiplication, division, and binary shift
operators are not supported. These can be implemented through functions.

121
doc/ctype.txt Normal file
View File

@ -0,0 +1,121 @@
Character Checking and Conversion Functions for C02
This library provides functions for classifying ASCII characters, as
well as converting upper-case characters to lower-case characters
and vice-versa.
The character classification functions return a value of -1 ($FF)
for TRUE, and 0 for FALSE. All these functions return FALSE when
passed a high ASCII character (127 - 255).
#include <ctype.h02>
The following functions are defined:
b = isalnm(c); Returns TRUE if c is alphanumeric, otherwise FALSE.
An alphanumeric character is a letter (A-Z or a-z),
or a digit (0-9).
Note: Calls internal routine isaln, which in turn
calls internal routines isdgt and isalp.
b = isalph(c); Returns TRUE if c is alphabetic, otherwise FALSE.
An alphabetic character is a letter (A-Z or a-z).
Note: Call internal routine isalp, which in turn
calls internal routines isupr and islwr.
b = isbdgt(c); Returns TRUE if c is a binary digit, otherwise FALSE.
A binary digit is a character in the range 0 through 1.
Note: Calls internal routine isbin, which shares code
with the internal routine isdgt.
b = isctrl(c); Returns TRUE if c is a control characte, otherwise FALSE.
A control character is a character with ASCII code
0 through 31 or 127.
Note: Calls internal routine isctl.
b = isdigt(c); Returns TRUE if c is a digit, otherwise FALSE.
A digit is a character in the range 0 through 9.
Note: Calls internal routine isdgt.
b = isgrph(c); Returns TRUE if c is graphical, otherwise FALSE.
A graphical character is any character in the
range ! through |.
Note: Calls internal routine isgrp, which in turn
calls internal routine isprt.
b = ishdgt(c); Returns TRUE if c is a hex digit, otherwise FALSE.
A hex digit is a character in the range 0 through 9.
A through F, or a through f.
Note: Calls internal routine ishex, which in turn
calls internal routine isdgt.
b = islowr(c); Returns TRUE if c is lowercase, otherwise FALSE.
An alphabetic character is a letter in the range
a through z.
Note: Call internal routine islwr.
b = ispnct(c); Returns TRUE if c is punctuation, otherwise FALSE.
A punctuation character is any graphical character
that is not aplhapnumeric.
Note: Calls internal routine ispnc, which in turn
calls internal routines isalp and isgrp.
b = isprnt(c); Returns TRUE if c is printable, otherwise FALSE.
A printable character is any character in the
range Space through |.
Note: Calls internal routine isprt.
b = isspce(c); Returns TRUE if c is white space, otherwise FALSE.
The white space characters are Tab (9), Line Feed (10),
Vertical Tab (11), Form Feed (12), Carriage Return (13),
and Space (32).
Note: Calls internal routine isspc.
b = isuppr(c); Returns TRUE if c is upper case, otherwise FALSE.
An uppercase character is a letter in the range
A through Z.
Note: Call internal routine isupr.
t = tolowr(c); Returns lower case version of c if it is an upper case
character, otherwise c.
Note: Calls internal routine isupr.
t = touppr(c); Returns upper case version of c if it is a lower case
character, otherwise c.
Note: Calls internal routine islwr.
Note: This library has no external dependencies.
Implementation: The standard method of implementing the ctype library is to
use a bit mask table of 128 bytes (one for each standard ASCII character).
This library instead uses a series of comparisons in the internal routines,
which leave the accumulator unmodified, and occupies approximately 128 bytes
of memory.

139
doc/file.txt Normal file
View File

@ -0,0 +1,139 @@
File System Input/Output Functions for C02 Programs
This library contains functions for file handling. These functions
are included here instead of in stdio.h because not all 6502 systems
support file based input/output. Functions that are not part of the
standard C libraries begin with the letters "fs".
At the beginning of the program use the directives
#include <stdio.h02>
#include <file.h02>
The following functions are defined:
fsinit(); Initialize file system.
This function should be called before calling
before any other file functions.
Note: Closes any open files and initializes
the library's internal file table.
f = fsptr(); Find an available file pointer.
Returns 0 if no more file pointers are available.
Note: This is called by the fopen() function, which
does the actual file allocation and is of limited
use in application programming.
r = fschk(f); Check to see if f is a valid file pointer.
Returns 0 if valid, otherwise 255.
Note: Called by the fclose(), feof(), fgetc(),
fgets(), fputc(), fputs(), fread(), and fwrite()
functions.
r = fstat(f); Get status of file table entry or last file error.
If f is 0, returns a system dependent value
corresponding to the last filesystem I/O error.
If f is a potentially valid file pointer. returns a
value representing the state of the corresponding
entry in the file table. If the file table entry is
unused, then a 0 is returned. Otherwise, a system
dependent system dependent value is returned.
If f does not point to a valid file table entry,
then 255 is returned.
Note: On CBM machines, fstat(0) returns the result
of READST directly after the last error. Valid file
pointer values are between 1 and FOMAX, inclusive
and return a value with bits 0 through 3 containing
the Kernal device number, and bit 7 set if an End of
File or other error was encountered.
f = fopen(d, &n); Open file specified from null-terminated string n
on device d, returning a pointer to the file.
Return 0 if the file could not be opened.
Note: On CBM machines, d is the device number and
f is a logical file nunber as used in a Basic Open
statement. Up to 7 files may be opened at a time.
r = fclose(f); Close file pointed to by f, returning 0 if
successful or 255 if there was an error.
Note: Returns 255 if f is not a valid file pointer.
c = fgetc(f); Read character from file opened to by filepointer f.
Returns character read from file.
Note: Returns 255 if f is not a valid file pointer.
Returns a system dependent garbage character if end
of file has been reached or any other I/O error. Use
feof(f) and fstat(0) to check for these conditions.
fputc(f, c); Write character c to file opened to filepointer f.
Use feof(f) and fstat(0) to check for errors after
write.
-----------------------------------------------------------------
r = getstr(&s); Reads a maximum of 128 characters from keyboard
until the Return/Enter key is pressed, storing the
entered characters as null-terminated string s.
Allows corrections using Backspace/Delete.
Pressing the Escape/Abort key terminates entry,
leaving the string in an undefined state.
Returns number of characters entered, or 255
if entry was aborted.
Note: Calls getchr() in a loop and uses constants
DELKEY, RTNKEY, and ESCKEY from the system library.
r = putstr(&s): Writes up to 128 characters of null-terminated
string s to the screen and advances the cursor to
the beginning of the next line.
Returns number of characters printed.
Note: Calls outstr(&s) followed by newlin().
Note: This library expects the following functions to be defined:
setdst(&s); Set destination string pointer
setsrc(&s); Set source string pointer and initialize index
along with the zero page variable pairs
dstlo,dsthi: Destination string pointer
srclo,srchi: Source string pointer
the static array
ftbl[FOMAX]
and the assembler constant
FOMAX The maximum number of files that can be opened
at one time.
as well as the data structure
FTBL A system dependent table of bytes containing data
related to files opened by the fopen() function.
See function fstat() for more information.

90
doc/func-idx.txt Normal file
View File

@ -0,0 +1,90 @@
Function Library Name Description
abs stdlib Absolute Value Return absolute value of byte.
atoc stdlib ASCII to Character Convert numeric string to byte.
blkbgn block Block Begin Set beginning of block address.
blkend block Block End Set end of block address.
blkseg block Block Segment Set block segment size.
blkset block Block Set Fill entire block with character.
blkrst block Block Reset Set block pointer to beginning of block.
blknxt block Block Next Move block pointer forward one segment.
blkput block Block Append Copy bytes from array to current segment.
blkget block Block Get Copy bytes from current segment to array.
blkmem block Block Memory Search block for segment matching array.
blkstr block Block String Search block for segment beginning with string.
blkswp block Block Swap Swap bytes of array with the current segment.
blksrt block Block Sort Sort segments in block by initial string.
ctoa stdlib Character to ASCII Convert byte to numeric string.
div stdlib Divide Divide two bytes.
fclall file File Close All Close all files.
fclose file File Close Close file.
feof file File End of File Check for end of file condition.
ferror file File Error Get file error information.
fgetc file File Get Character Read character from file.
fgets file File Get String Read string from file.
fopen file File Open Open file.
fputc file File Put Character Write character to file.
fputs file File Put String Write string to file.
fread file File Read Read bytes from file.
fschk file File System Check Check for valid file pointer
fsdst file File Set Destination Set destination array for fread.
fsinit file File System Init Initialize file system.
fsptr file File System Pointer Get unused file pointer.
fssrc file File Set Source Set source array for fwrite.
fstat file File System Status Get file pointer status.
fwrite file File Write Write bytes to file.
getchr stdio Get Character Read character from keyboard.
isalnm ctype Is Alphanumeric Return TRUE if character is A-Z, a-z, or 0-9.
isalph ctype Is Alphabetic Return TRUE if character is A-Z or a-z.
isbdgt ctype Is Binary Digit Return TRUE if character is 0 or 1.
isctrl ctype is Control Return TRUE if ASCII code is 0-31 or 127.
isdigt ctype Is Digit Return TRUE if character is 0-9.
isgrph ctype Is Graphical Return TRUE if ASCII code is 33-126.
ishdgt ctype Is Hex Digit Return TRUE if character is 0-9, A-F, or a-f.
islowr ctype Is Lowercase Return TRUE if character is a-z.
ispnct ctype Is Punctuation Return TRUE if Graphical and not Alphanumeric.
isprnt ctype Is Printable Return TRUE if ASCII code is 32-126.
isspce ctype Is white Space Return TRUE if ASCII code is 9-13 or 32.
isuppr ctype Is Uppercase Return TRUE if character is A-Z.
max stdlib Maximum Return greater of two byte.
memdst memory Memory Destination Set destination array for subsequent functions.
memset memory Memory Set File bytes in array with character.
memchr memory Memory Character Search for byte in array.
memcmp memory Memory Compare Compare bytes in array against destination array.
memcpy memory Memory Copy Copy bytes from array to destination array.
memswp memory Memory Swap Swap bytes in array with destination array.
min stdlib Minimum Return lesser of two byte.
mult stdlib Multiply Multiply two bytes.
ptrset pointer Pointer Set Set pointer to address.
ptrput pointer Pointer Put Write byte and increment pointer.
ptrget pointer Pointer Get Read byte and increment pointer.
ptrinc pointer Pointer Increment Increment pointer.
ptrdec pointer Pointer Decrement Decrement pointer.
ptradd pointer Pointer Add Add value to pointer.
ptrsub pointer Pointer Subtract Subtract value from pointer.
ptrcmp pointer Pointer Compare Compare pointer against address.
ptrsav pointer Pointer Save Save pointer into two-byte array.
ptrrst pointer Pointer Restore Restore pointer from two-byte array.
putchr stdio Put Character Write character to screen.
getstr stdio Get String Read string from keyboard.
outstr stdio Output String Write string to screen.
outsub stdio Output Substring Write substring to screen.
putstr stdio Put String Write string plus newline to screen.
rand stdlib Random Generate pseudorandom number.
rands stdlib Random Seed Seed random number generator.
shiftl stdlib Shift Left Shift byte left specified number of bits.
shiftr stdlib Shift Right Shift byte right specified number of bits.
strapd string String Append Append character to string.
strcat string String Concatenate Concatenate string to destination string.
strchr string String Character Search for character in string.
strcmp string String Compare Compare string contents against destination string.
strcpy string String Copy Copy string contents to destination string.
strcsp stringx String Char Span Return length of span in destination not in string.
strcut string String Cut Copy substring to destination string.
strdst string String Destination Set destination string for subsequent functions.
strlen string String Length Calculate length of string.
strpbk stringx String Pointer Break Find first character in destination found in string.
strrch string String Reverse Char Search for character from end of string.
strspn stringx String Span Return length of span in destination found in string.
strstr string String String Search for string in destination string.
tolowr ctype To Lowercase Convert character to lowercase.
touppr ctype To Uppercase Convert character to uppercase.

83
doc/header.txt Normal file
View File

@ -0,0 +1,83 @@
System Specific Header File Specification
The very first directive of the program must be
#include <header.h02>
where header.h02 is the system specific header file, (e.g. apple1.h02,
vic20.h02, etc.).
Note: This will probably be replaced with a command line parameter
(e.g. '-s apple1', '-s vic20', etc...) to allow program portability.
If compatibility with the C02 Standard Libraries is needed, the following
functions must be defined:
c = plkey(); Polls keyboard and returns raw ASCII character
corresponding to last/current pressed key.
Returns constant NULKEY (usually 0) if no key was
pressed.
c = rdkey(); Waits for a keypress and returns the raw ASCII
character corresponding to the pressed key.
Note: Usually a loop that calls plkey(), but may
also directly call a system subroutine.
c = getkey(); Waits for a keypress and returns the cleaned
ASCII value corresponding to the pressed key.
Note: Calls rdkey() followed by any necessary
character code conversions. This can be due to
high-bit being set by keyboard decoder,
non-standard key mappings, keys that generate
escape sequences, etc...
newlin(); Advances the cursor to the beginning of then
next line.
Note: Depending on the system, this will usually
output a Carriage Return, Line Feed, both.
prchr(c); Writes character c to the screen.
Note: May directly access memory-mapped I/O
or may call a system subroutine.
setdst(&s): Stores pointer to &s in dstlo and dsthi.
setsrc(&s): Stores pointer to &s in srclo and srchi and
initializes Y register to 0.
along with the Zero Page locations (each pair of which must be sequential)
srclo, srchi Spurce String Pointer
dstlo, dsthi Destination String Pointer
the following locations that may be Zero Page, but don't have to before
temp0 Temporary variables used by stdlib.asm
temp1
temp2
and the following locations that must be preserved between function calls
random Storage for the Random Number Generator
Contains the last number generated and is used to
generate the next number in the sequence
rdseed Seed for Pseudo-Random Number Generator
Usually a counter or timer. If one is not provided
by the system, should be generated by incrementing
in the plkey(), rdkey() functions.
and the constants
DELKEY ASCII code for Delete/Backspace key (usually DEL or BS)
ESCKEY ASCII code for Escape/Abort key (usually ESC)
NULKEY Returned if no Key was Pressed
RTNKEY ASCII code for Return/Enter key (usually CR)

50
doc/keywords.txt Normal file
View File

@ -0,0 +1,50 @@
Standard C Keywords
break
case
char
const
continue
default
do
else
for
goto
if
return
switch
void
while
C Preprocessor directives
#define
#error
#include
#pragma
Questionable C Keywords
enum
extern
register
signed
sizeof
struct
typedef
union
unsigned
volatile
Unused Standard C Keywords
auto n/a
double n/a
float n/a
int n/a
long n/a
short n/a
static n/a
Unused Preprocessor Directives
#if
#ifdef
#ifndef
#undef
# line

82
doc/memory.txt Normal file
View File

@ -0,0 +1,82 @@
Array Manipulation Functions for C02
This library contains functions for handling non-string arrays. It is
maintained separately from string.h so that it can be included only
when needed, in order to reduce program size.
Arrays may be declared with up to 256 elements, but only lengths of up
to 255 characters may be passed to the array handling functions.
Usage: at the beginning of the program use the directives
#include <memory.h02>
The following functions are defined:
memdst(&d); Sets array d as the destination array for subsequent
memchr(). memcmp(), strcpy(), and memset() calls.
This function is not part of the standard C and
C++ string libraries. It is needed because of the
parameter passing limitations of C02.
Note: Aliased to the setdst() routine which sets
variables dstlo and dsthi as a pointer to the array.
memset(c, n); Fills first n bytes of the destination array set
by a a prior memdst() call with character c.
Note: dstlo and dsthi are left pointing to the
destination array.
p = memchr(c, n); Searches for character c in the first n bytes of the
destination array set by a a prior memdst() call.
Returns position of first occurance of character
in array, or 255 if character was not found or a
length of 0 was specified.
Note: dstlo and dsthi are left pointing to the
destination array.
c = memcmp(n, &s); Compares up to n bytes of source array s against the
destination array set by a prior memdst() call.
Returns 255 if destination < source, 0 if
destination = source, and 1 if destination > source.
These results can be evaluated using the C02
unary comparator ! or the test-operators :+ or :-.
Note: dstlo and dsthi are left pointing to the
destination array.
memcpy(n, &s); Copies n bytes of source array s into destination
array set by prior memdst() call. Data in the
destination array starting at position n is left
undisturbed.
Note: dstlo and dsthi are left pointing to the
destination array.
memswp(n, &s); Swaps n bytes of source array s with destination
array set by prior memdst() call. Data in both
arrays starting at position n is left undisturbed.
Note: dstlo and dsthi are left pointing to the
destination array.
Note: This library expects the following functions to be defined
setdst(&s); Set destination string pointer
setsrc(&s); Set source string pointer and initialize index
along with the zero page pairs
strlo, strhi Source String Pointer
dstlo, dsthi Destination String Pointer
and the memory locations
temp0, temp1 Temporary storage

54
doc/notes.txt Normal file
View File

@ -0,0 +1,54 @@
Keywords:
break complete
case unimplemented
char incomplete
const unimplemented
continue complete
default unimplemented
do incomplete - break/continue don't work
else complete
for complete
goto complete
if complete
return untested
switch unimplemented
void incomplete
while complete
Features:
comparisons variable type checking not implemented
functions definition incomplete
Conditional Operator Bit-Mask
Character
= 1
< 2
> 4
Comparator Complement
== 1 6 <>
< 2 5 >=
<= 3 4 >
> 4 3 <=
>= 5 2 <
<> 6 1 ==
XOR 7 Reverses Operator!!!
Block Sort Algorithm
;blkptr = blkbgn
;while blkptr < blkend
; dst = blkptr
; src = blkptr
; while dst += seglen < blkend
; if *dst < *src
; src = dst
; if src <> blkptr
; *m = *src
; *src = *blkptr
; *blkptr = *m
; blkptr += seglen

139
doc/pointer.txt Normal file
View File

@ -0,0 +1,139 @@
Pointer Functions
This library contains functions for basic pointer access and manipulation.
These functions are intended to allow sequential reading and writing of
individual bytes to arbitrary locations in memory.
Only one pointer may be active at a time, but it's contents may be saved
and restored.
Note: There is no concept of a null pointer in C02. A pointer containing
the value 0 simply points to the first byte of memory.
In the equivalent C code examples below, the system pointer is represented
as the variable p. In all cases, assume the following declaration :
int *p;
Usage: at the beginning of the program use the directives
#include <pointer.h02>
The following application functions are defined:
ptrset(&v); Pointer Set: Set pointer contents to the address of
variable v.
This is equivalent to the C code
p = &v;
Note: Sets variables ptrlo and ptrhi.
ptrput(b); Pointer Put: Stores value of b in the byte currently
pointed to and increments the pointer.
This is equivalent to the C code
*p = b; p++;
Note: Updates variables ptrlo and ptrhi.
b = ptrget(); Pointer Get: Retrieves the contents of the byte
currently pointed to and increments the pointer.
This is equivalent to the C code
b = *p; p++;
Note: Updates variables ptrlo and ptrhi.
ptrinc(); Pointer Increment: Increases the pointer value by 1,
causing it to point to the next byte in memory.
This is equivalent to the C code
p++;
Note: Updates variables ptrlo and ptrhi.
ptrdec(); Pointer Decrement: Decreases the pointer value by 1,
causing it to point to the previous byte in memory.
This is equivalent to the C code
p++;
Note: Updates variables ptrlo and ptrhi.
ptradd(n); Pointer Add: Adds the value n to the address contained
in the pointer, moving it that many bytes forward in
memory.
This is equivalent to the C code
p += n;
Note: Updates variables ptrlo and ptrhi.
ptrsub(n); Pointer Subtract: Adds the value n to the address
contained in the pointer, moving it that many bytes
backward in memory.
This is equivalent to the C code
p -= n;
Note: Updates variables ptrlo and ptrhi.
ptrcmp(&v); Pointer Compare: Compares pointer contents against
the address of variable v.
Returns 255 if the pointer is less than the address
(pointing to a byte lower in memory), 0 if the pointer
is equal to the address (pointing to the same byte),
and 1 if greater than tge address (pointing to a
byte higher in memory).
These results can be evaluated using the C02
unary comparator ! or the test-operators :+ or :-.
This is equivalent to the C code
if (p < &v) return 255;
else if (p > &v) return 1;
else return 0;
Note: Sets variables srclo and srchi.
ptrsav(&r); Pointer Save: Copies the pointer contents into the
first to bytes of array r.
This is roughly equivalent to the C code
r = (int) p;
Note: Sets variables srclo, srchi, and temp0.
ptrrst(&r); Pointer Restore: Copies the first to bytes of array r
into the pointer contents.
This is roughly equivalent to the C code
p = (void*) r;
Note: Sets variables srclo, srchi, ptrlo, and ptrhi.
Note: This library expects the following functions to be defined
setsrc(&s); Set source string pointer and initialize index
along with the zero page variable pairs
strlo, strhi Source String Pointer
as well as the transient variable
temp0 Temporary storage

BIN
doc/quickref.odt Normal file

Binary file not shown.

113
doc/screen.txt Normal file
View File

@ -0,0 +1,113 @@
Screen Control Functions for C02
This is a prototype definition for a library providing functions
to manipulate the screen and move the cursor. Since this code is
highly system dependent, a separate library will need to be
created for each system type.
The following functions should be defined:
clrscn(); Clears the screen and returns the cursor to the
home position.
Note: May call a system routine, or may print
"clear screen" character sequence.
crsrhm(); Moves cursor to home position (upper left corner
of the screen).
Note: May call mvcrsr(0,0); or may print "cursor
home" character sequence.
crsrlf(); Moves cursor one column to the left. May or may not
screen wrap, depending on system.
Note: May call mvcrsr; or may print "cursor left"
character sequence.
crsrrt(); Moves cursor one column to the right. May or may not
screen wrap, depending on system.
Note: May call mvcrsr; or may print "cursor right"
character sequence.
crsrup(); Moves cursor one row up.
Note: May call mvcrsr; or may print "cursor up"
character sequence.
crsrdn(); Moves cursor one row down.
Note: May call mvcrsr; or may print "cursor down"
character sequence.
mvcrsr(r, c); Moves cursor to row r, column c.
Note: May call system routine, or set system variables.
h = scnhgt(); Returns screen height in rows.
Note: May call system routine, or read system variable.
w = scnwid(); Returns screen width in columns.
Note: May call system routine, or read system variable.
c = scncol(); Returns current screen column.
Note: May call system routine, or read system variable.
r = scnrow(); Returns current screen row.
Note: May call system routine, or read system variable.
txtclr(c); Sets text color to system color c.
Note: May call system routine or may print color change
sequence.
bkgclr(c); Sets background color to system color c.
Note: May call system routine or may print color change
sequence.
Assembly Constants (Defined in System Header file)
BLACK Code for color Black
BLUE Code for color Blue
GREEN Code for color Green
CYAN Code for color Cyan
RED Code for color Red
MAGNTA Code for color Magenta
YELLOW Code for color Yellow
WHITE Code for color White
BREAK ASCII code for Break/Stop Key
BCKSPC ASCII code for Backspace key
CLEAR ASCII code for Clear Key
DELETE ASCII code for Delete key
DOWN ASCII code for Cursor Down Key
ENTER ASCII code for Return/Enter key (usually CR)
ESCAPE ASCII code for Escape/Abort key (usually ESC)
FNx ASCII code for Function Key x
HOME ASCII code for Home Key
INSERT ASCII code for Insert Key
LEFT ASCII code for Cursor Left Key
RIGHT ASCII code for Cursor Left Key
TAB ASCII code for Tab Key
UP ASCII code for Cursor Up Key
BTMLFT ASCII code for Box Drawing Bottom Left Corner
BTMRGT ASCII code for Box Drawing Bottom Right Corner
BTMTEE ASCII code for Box Drawing Bottom to Cetter Tee
CTRCRS ASCII code for Box Drawing Center Cross
HRZLIN ASCII code for Box Drawing Horizontal Line
LFTTEE ASCII code for Box Drawing Left To Center T
RGHTEE ASCII code for Box Drawing Right To Center T
TOPLFT ASCII code for Box Drawing Top Left Corner
TOPRGT ASCII code for Box Drawing Top Right Corner
TOPTEE ASCII code for Box Drawing Top to Center T
VRTLIN ASCII code for Box Drawing Verical Line

155
doc/small-c.txt Normal file
View File

@ -0,0 +1,155 @@
Types
char — 8 bit data element
int — 16 bit data element
Declarations
type name — declares name to be element
type *name — declares name to be pointer to element of specified type
type name[] — syntactically identical to above pointer declaration
type name[constant] — declares an array of "constant” size where
each array element is of specified type
Constants
Decimal number.
Single or pair of ASCII characters enclosed in single quotes,
such as a or T X .
String enclosed in double quotes, such as “this is a string”.
The value such a constant yields is a pointer to the first character
of the string which the compiler stores in memory.
Function Calls
Defined as any expression followed by an open paren. Thus, a function
can be to a named routine, such as “print()” , or to the results of some
expression, such as “1000()” (which calls location 1000 decimal), or
“array[i]()” which calls the location whose value is found in array[i] .
Subscripted elements.
Either an array name or a pointer may be subscripted to refer to the
appropriate element. Subscripts are assumed to start from zero. Therefore,
legal expressions are:
array [0] - the first element in array,
array [x+31] — the element at the address given by adding x to 31
and then to array,
pointer [i] — the elemen t at the address given by adding i to the
contents of pointer.
Only single dimensions are allowed. Subscripting either an integer array
or a pointer to an integer will cause the subscript expression to be
doubled. Therefore, if you declare “int *ptr”, the expression “ptr[3]”
refers to the element at ptr+6.
Unary Expression Operators
"-" — forms the twos complement of the expression (minus).
“*” — refers to the element pointed to by the expression
(providing the expression is a pointer).
“&” — evaluates the address of the given expression, providing
it hasone. Hence, &count yields the address of the element
“count”. &1000 is an error.
“&” — increments the expression by one. If this appears before the
expression, it increments before using it. If it appears after
it, it will increment it after. Only values (expressions which
can appear on the left-hand side of an equal sign) are allowed.
Hence, assuming “count” contains a 5, ++count would evaluate to
a 6, and “count” would contain a 6. Likewise, count++ would
evaluate to a 5, and count would contain a 6. 1000++ is illegal.
If this operator is applied to an integer pointer, it will
increment by 2.
"--" — decrements the expression by one. This works just like ++ but
subtracts one rather than adding.
Binary Operators
“+” — adds the two expressions (i.e. count + total)
"-" — subtracts the two expressions.
“*” — multiplies the two expressions.
“/” — divides the first expression by the second.
"%" — yields the remainder after dividing the first expression
by the second (modulo).
“|” — yields the logical inclusive “or” of the two expressions.
"^" — yields the logical exclusive “or” of the two expressions.
"&" — yields the logical “and” of the two expressions.
“=” — assigns the value of the expression on the right to the one
on the left. Since evaluation is done right to left in this
case, syntaxes like "x = y = z" are legal.
Comparison Operators
“==” — tests for equality.
“==” — tests for inequality.
“<” — tests for less than.
“>” — tests for greater than.
“<=” — tests for less than or equal to
“>=” — tests for greater than or equal to
Comparisons involving a pointer (which is an address) are done
as unsigned compares. All other compares are signed.
Statements
expression; An expression, no matter how complex, is considered
a simple statement.
if (expression); If the expression is non-zero, the statement
is executed , otherwise it isnt.
if (expression) statement; else statement; This form of the “if”
statement allows the “else” clause. As is the case with most
“dangling else” ambiguities, all “else" statements pair with
the nearest unmatched “if".
while (expression) statement; The statement is performed until
the expression becomes zero. Since the test is made before the
statement is executed the first time, it need not be executed
at all.
break; This statement will cause control to be transferred out
of the inner-most “while” loop.
continue; This statement, used within a “while” loop, will transfer
control back to the top of the loop.
return; This statement does an immediate return from the current
function . If a function does not end with this statement, one
is performed regardless.
return expression; This statement allows a function to return a
value explicitly.
; A semicolon by itself is considered a null statement which does
nothing but take the place of a statement. You see this in forms
such as: “while (*iptr++ = *jptr++);” where the test itself
contains all the necessary parts of the statement.
{statement; statement;. . . ; statement;} The use of curly brackets
(“{ }”) around any group of simple statements is considered a
compound statement. A compound statement can be used anywhere a
simple statement can. For example:
while (1) {x = 3; y = 10; funct(33);}
or
if (x< y)
{ print(x);
total (x);
--x;
}
else
{ type(“all done”);
x = y;
}
Pseudo-ops
#include filename — Anywhere this statement appears in the program,
the indicated filename will be opened and inserted. The “included”
file may not contain an “#include” statement.
#define name string — This statement will cause the given name to
be replaced by the string throughout the entire program . Normally,
it is used to define constants, such as:
#define tablesize 1000
#define maxlength 8
But it can also be used for any sort of text:
#define jprint 3crs print(12); print(12); print(l2);
The replacem ent is purely on a text level, and error checking will
be performed only after the replacement.
#asm . . . #endasm — This structure is not supported by standard C,
but it was a feature I felt I needed. It may appear anywhere a statement
would, but it passes everything between the word “#asm” and the word
“#endasm” right through the parser without intervention. It is intended
to be used to pass assembly language code through the parsing mechanism.
Since it counts as a single statement, allowable (and expected) forms are:
if (x < y)
#asm
LHLD TOTAL
CALL ADD
CNC ERROR
#end asm
else return;
This pseudo-op conceivably allows an entire assembly language program to
be passed through the compiler. Its intent is to allow machine dependent
features (like the 8080s “IN” and “OUT” instructions to be used without
writing separate programs).

72
doc/stdio.txt Normal file
View File

@ -0,0 +1,72 @@
Standard Input/Output Functions for C02 Programs
At the beginning of the program use the directives
#include <stdio.h02>
The following functions are defined:
c = getchr(); Waits for a keypress and returns the cleaned
ASCII value corresponding to the pressed key.
Note: Aliased to getkey() from system library.
putchr(c); Writes character c to the screen.
Note: Aliased to prchr() from system library.
r = getstr(&s); Reads a maximum of 128 characters from keyboard
until the Return/Enter key is pressed, storing the
entered characters as null-terminated string s.
Allows corrections using Backspace/Delete.
Pressing the Escape/Abort key terminates entry,
leaving the string in an undefined state.
Returns number of characters entered, or 255
if entry was aborted.
Note: Calls getchr() in a loop and uses constants
DELKEY, RTNKEY, and ESCKEY from the system library.
r = outstr(&s): Writes up to 128 characters of null-terminated
string s to the screen.
Returns position of null terminator in string.
Note: Calls outsub(0, &s).
r = outsub(n, &s): Writes up to 128 characters of null-terminated
string s to the screen, starting at position n.
Returns position of null terminator in string.
Note: Calls putchr() in a loop.
r = putstr(&s): Writes up to 128 characters of null-terminated
string s to the screen and advances the cursor to
the beginning of the next line.
Returns number of characters printed.
Note: Calls outstr(&s) followed by newlin().
Note: This library expects the following functions to be defined:
getkey(); Wait for and read ASCII character from keyboard
prchr(c); Print ASCII character to screen
delchr(); Backspace and delete previous character on screen
newlin(); Advance cursor to beginning of next line
setsrc(&s); Set source string pointer and initialize index
along with the zero page variable pairs
srclo,srchi: Source string pointer
and the assembler constants
DELKEY Delete/Backspace key ASCII code (usually DEL or BS)
ESCKEY Escape/Abort key ASCII code (usually ESC)
RTNKEY Return/Enter key ASCII code (usually CR)

100
doc/stdlib.txt Normal file
View File

@ -0,0 +1,100 @@
Standard Library Functions for C02 Programs
At the beginning of the program use the directives
#include <stdlib.h02>
The following functions are defined:
c = abs(b); Returns the absolute value of the two's-complement
byte b.
In two's-complement arithmetic, the unsigned values
0 - 127 are considered positive, while the unsigned
values 128 - 255 are considered negative.
c = atoc(&s); Returns the numeric value of the string in array s.
Does not skip leading white-space characters and
stops when first non-digit character is encountered.
Overflows are ignored, so numbers greater than 255
will be returned modulo 256.
ctoa(c, &s); Stores the ASCII representation of usigned byte c
as a null-terminated string in array s.
The array must be dimensioned to at least 4 bytes.
c = max(b, d); Returns the greater of the two unsigned bytes b and d.
c = min(b, d); Returns the lesser of the two unsigned bytes b and d.
c = mult(d, r); Returns the product of byte d times byte r.
Overflows are ignored, so results greater than 255
will be returned modulo 256.
c = div(n, d); Returns the quotient of byte n divided by byte d.
Remainders are discarded and division by 0 returns ??.
c = rand(); Returns pseudo-random number. Sequence repeats
after 255 repeated calls. The generator must be
seeded using the rands() function before the first
call to rand().
rands(n); Seeds the pseudo-random number generator.
If n is 0, the generator is seeded with a system
seed value. This should be used for normal operation.
If n is not 0. then it is used as the seed. This can
be used for program testing or when a predictable
pattern is needed.
Note: The system seed is generated by a counter or
timer. On systems that don't use a timer, the counter
is cycled by the keyboard routines, so the getkey()
or getchr() function must called at least once before
a rands(0) call.
c = shiftl(b, n); Returns byte b shifted n bits to the left, filling
with 0's from the right.
If n is greater than 8, all bits will be shifted out,
and a value of 0 is treated as 256.
c = shiftr(b, n); Returns byte b shifted n bits to the right, filling
with 0's from the left.
If n is greater than 8, all bits will be shifted out,
and a value of 0 is treated as 256.
Note: Using the shiftl() or shiftr() functions with
an asignment generates 9 to 12 bytes of code, whereas
the << and >> post-operators generate either 2 or 3
bytes each. So for a constant number of shifts, the
post-operators will generate smaller code for less
than 5 shifts and will always be faster.
Note: This library expects the following function to be defined
setsrc(&s); Set source string pointer and initialize index
along with the zero page variables
srclo,srchi: Source string pointer
as well as the transient variables
temp0 Temporary storage
temp1
temp2
and the static variables
random Psuedo-random number generator seed Value
rdseed System generated initial seed (counter or timer)

138
doc/string.txt Normal file
View File

@ -0,0 +1,138 @@
Common String Manipulation Functions for C02
Strings are zero-terminated arrays of type char with a maximum length
of 128 characters.
The first character in a string is at position 0, and the last character
is at position length minus 1.
Since all of the routines stop processing at the 128th character, a 128
character string does not require a zero terminator.
Due to the limitations of parameter passing in C02, the argument lists of
most of these functions do not match those in standard C and C++.
Usage: at the beginning of the program use the directives
#include <string.h02>
The following functions are defined:
p = strapd(c, &s); Append character c to string s.
Returns length of new string.
If the string length exceeds 127 prior to the
append, no action is taken and the existing
length is returned.
This function is not part of the standard C and
C++ string libraries. It is included because it
is more efficient than the equivalent C02 code.
p = strchr(c, &s); Searches string s for character c.
Returns position of first occurance of character
in string, or 255 if character was not found.
n = strlen(&s); Determines length of string s.
Returns length of string.
p = strrch(c, &s); Searches end of string s for character c.
Returns position of last occurance of character
in string, or 255 if character was not found.
strdst(&d); Sets string d as the destination string for subsequent
strcat(). strcmp(), strcpy(), and strstr() calls.
This function is not part of the standard C and
C++ string libraries. It is needed because of the
parameter passing limitations of C02.
Note: Aliased to the setdst() routine which sets
variables dstlo and dsthi as a pointer to the string.
n = strcat(&s); Concatenates source string s onto the end of
destination string set by prior strdst() call.
Returns total length of concatenated string.
Note: dstlo and dsthi are left pointing to the
destination string.
c = strcmp(&s); Compares source string s against destination
string set by prior strdst() call.
Returns 255 if destination < source, 0 if
destination = source, and 1 if destination > source.
These results can be evaluated using the C02
unary comparator ! or the test-operators :+ or :-.
Note: dstlo and dsthi are left pointing to the
destination string.
n = strcpy(&s); Copies wource string s into destination string set
by prior strdst() call, replacing previous contents.
Returns number of characters copied.
Note: dstlo and dsthi are left pointing to the
destination string.
To copy the first n characters from string s to
string d, the following code can be used:
strdst(&d); strcpy(&s); s[n]=0;
n = strcut(n, &s); Copies from source string s, starting at position n,
into destination string set by prior strdst() call,
replacing previous contents.
Returns number of characters copied.
This function is not part of the standard C and
C++ string libraries. It is included because
it is faster and more compact tham the equivalent
C02 code.
To copy a substring starting at position n with
length l from string s to string d, the following
code can be used:
strdst(&d); strcut(&s, n); s[l]=0;
Note: calls routine strcat(). leaving dstlo and
dsthi pointing to the destination string, along
with strlo and strhi pointing to the address of
position n in the source string.
p = strstr(&s); Searches for destination string s in source string
set by prior strdst() call.
Returns position of source string in destination
string, or 255 if character was not found.
Note: calls routine strcmp(), leaving dstlo and
dsthi pointing to the address of the position of
the source string in the destination string (or
the end of the destination string if the source
string was not found).
Note: This library expects the following functions to be defined
setdst(&s); Set destination string pointer
setsrc(&s); Set source string pointer and initialize index
along with the zero page variable pairs
strlo, strhi Source String Pointer
dstlo, dsthi Destination String Pointer
as well as the transient variables
temp0 Temporary storage
temp1

67
doc/stringx.txt Normal file
View File

@ -0,0 +1,67 @@
Extended String Manipulation Functions for C02
This library contains less commonly used string functions. It is maintained
as a separate set of files so that it can be included only when needed, in
order to reduce program size.
Strings follow all the same rules as specified in the string.h02 library.
Usage: at the beginning of the program use the directives
#include <string.h02>
#include <stringx.h02>
The following functions are defined:
n = strspn(&s); Returns the length of the span of characters at
the beginning of destination string set by prior
strdst() call that are present in source string s.
This mimics the functionality of the standard C
and C++ strspn() function.
Note: calls routine strchr(), leaving dstlo and
dsthi pointing to the destination string.
n = strcsp(&s); Returns the length of the span of characters at
the beginning of destination string set by prior
strdst() call that are not present in source
string s.
This mimics the functionality of the standard C
and C++ strcspn() function.
Note: aliased to the strbrk() function, which calls
strchr(), leaving dstlo and dsthi pointing to the
destination string.
n = strpbk(&s); Returns the poisition of the first character in
the destination string set by prior strdst() call
that is present in source string s.
If no characters in the source string are present
in the destination string, returns 255.
This mimics the functionality of the standard C
and C++ strpbrk() function.
Note: calls routine strchr(), leaving dstlo and
dsthi pointing to the destination string.
Note: This library expects the following functions to be defined
setdst(&s); Set destination string pointer
setsrc(&s); Set source string pointer and initialize index
strchr(c, &s); Return position of character in string
along with the zero page pairs
strlo, strhi Source String Pointer
dstlo, dsthi Destination String Pointer
and the memory locations
temp0, temp1 Temporary storage

17
doc/syntax.bnf Normal file
View File

@ -0,0 +1,17 @@
conditional := expression | expression comparator term
comparator := comparacter | comparacter comparacter
comparactor := '=' | '<' | '>'
operator := '+' | '-' | '&' | '|' | '^'
term := element | value
element := variable '[' value ']'
number := binary | decimal | hexadecimal
hexadecimal := '$' hexdigit hexdigit
decimal := digit | decimal digit
binary := '%' bit bit bit bit bit bit bit bit
letter := 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' |
'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' |
'W' | 'X' | 'Y' | 'Z'
hexdigit := digit | 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
digit := bit | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
bit := '0' | '1'