mirror of
https://github.com/RevCurtisP/C02.git
synced 2024-06-25 14:29:27 +00:00
Allow int members in structs
This commit is contained in:
parent
2530f3ed1e
commit
b6cec4d75a
6
c02.ppj
6
c02.ppj
|
@ -28,8 +28,8 @@ LIB = $(PellesCDir)\Lib\Win64;$(PellesCDir)\Lib#
|
||||||
# Build c02.exe.
|
# Build c02.exe.
|
||||||
#
|
#
|
||||||
c02.exe: \
|
c02.exe: \
|
||||||
output\c02.obj \
|
|
||||||
output\asm.obj \
|
output\asm.obj \
|
||||||
|
output\c02.obj \
|
||||||
output\common.obj \
|
output\common.obj \
|
||||||
output\cond.obj \
|
output\cond.obj \
|
||||||
output\dclrtn.obj \
|
output\dclrtn.obj \
|
||||||
|
@ -165,6 +165,7 @@ output\parse.obj: \
|
||||||
src\asm.h \
|
src\asm.h \
|
||||||
src\common.h \
|
src\common.h \
|
||||||
src\files.h \
|
src\files.h \
|
||||||
|
src\label.h \
|
||||||
src\parse.h
|
src\parse.h
|
||||||
$(CC) $(CCFLAGS) "$!" -Fo"$@"
|
$(CC) $(CCFLAGS) "$!" -Fo"$@"
|
||||||
|
|
||||||
|
@ -190,6 +191,7 @@ output\vars.obj: \
|
||||||
src\vars.c \
|
src\vars.c \
|
||||||
src\asm.h \
|
src\asm.h \
|
||||||
src\common.h \
|
src\common.h \
|
||||||
|
src\dclrtn.h \
|
||||||
src\files.h \
|
src\files.h \
|
||||||
src\label.h \
|
src\label.h \
|
||||||
src\parse.h \
|
src\parse.h \
|
||||||
|
@ -197,3 +199,5 @@ output\vars.obj: \
|
||||||
$(CC) $(CCFLAGS) "$!" -Fo"$@"
|
$(CC) $(CCFLAGS) "$!" -Fo"$@"
|
||||||
|
|
||||||
.SILENT:
|
.SILENT:
|
||||||
|
|
||||||
|
.EXCLUDEDFILES:
|
||||||
|
|
192
doc/c02.txt
192
doc/c02.txt
|
@ -287,13 +287,13 @@ generate sets of related but distinct values.
|
||||||
|
|
||||||
An enumeration is defined using an enum statement. When using the enum
|
An enumeration is defined using an enum statement. When using the enum
|
||||||
keyword, it is followed by a { character, one or more constant names
|
keyword, it is followed by a { character, one or more constant names
|
||||||
separated by commas, and a } character. An asterisk may be used in place
|
separated by commas, and a } character. A period may be used in place
|
||||||
of a constant name, in which case the sequence will be skipped. The enum
|
of a constant name, in which case the sequence will be skipped. The
|
||||||
statement is terminated with a semicolon.
|
enum statement is terminated with a semicolon.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
enum {BLACK, WHITE, RED, CYAN, PURPLE, GREEN, BLUE, YELLOW};
|
enum {BLACK, WHITE, RED, CYAN, PURPLE, GREEN, BLUE, YELLOW};
|
||||||
enum {*, FIRST, SECOND, THIRD};
|
enum {., FIRST, SECOND, THIRD};
|
||||||
enum {ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN};
|
enum {ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN};
|
||||||
|
|
||||||
Note: Values are automatically assigned to the constants in an enumeration.
|
Note: Values are automatically assigned to the constants in an enumeration.
|
||||||
|
@ -308,13 +308,13 @@ combined into a single char variable.
|
||||||
|
|
||||||
An enumeration is defined using a bitmask statement. When using the bitmask
|
An enumeration is defined using a bitmask statement. When using the bitmask
|
||||||
keyword, it is followed by a { character, one to eight constant names
|
keyword, it is followed by a { character, one to eight constant names
|
||||||
separated by commas, and a } character. An asterisk may be used in place
|
separated by commas, and a } character. A period may be used in place of a
|
||||||
of a constant name, in which case the bit value will be skipped. The
|
constant name, in which case the bit value will be skipped. The bitmask
|
||||||
bitmask statement is terminated with a semicolon.
|
statement is terminated with a semicolon.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
bitmask {BLUE, GREEN, RED, BRIGHT, INVERT, BLINK, FLIP, BKGRND};
|
bitmask {BLUE, GREEN, RED, BRIGHT, INVERT, BLINK, FLIP, BKGRND};
|
||||||
bitmask {RD, RTS, DTR, RI, CD, *, CTS, DSR};
|
bitmask {RD, RTS, DTR, RI, CD, ., CTS, DSR};
|
||||||
|
|
||||||
Note: Values are automatically assigned to the constants in a bitmask,
|
Note: Values are automatically assigned to the constants in a bitmask,
|
||||||
each of which is a sequential power of two. The first constant in the
|
each of which is a sequential power of two. The first constant in the
|
||||||
|
@ -323,43 +323,72 @@ the third is assigned the value 4, and so on.
|
||||||
|
|
||||||
DECLARATIONS
|
DECLARATIONS
|
||||||
|
|
||||||
A declaration statement consists of type keyword (char or void) followed
|
A declaration statement consists of type a keyword (char, int, or void)
|
||||||
by one or more variable names and optional definitions, or a single
|
followed one or more variable names (and optional definitions) or a single
|
||||||
function name and optional function block.
|
function name and optional function block, or the struct keyword followed
|
||||||
|
by a structure name and either a definition or a variable name.
|
||||||
|
|
||||||
Variables may only be of type char and all variable declaration statements
|
Variables may only be of type char or int, and all variable declaration
|
||||||
are suffixed with a ; character.
|
statements are suffixed with a ; character. Variables of type char may be
|
||||||
|
delared as arrays, by appending the variable name with the [ character,
|
||||||
|
the upper bound of the array (0 to 255), and the ] character.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
char c; //Defines variable c
|
char c; //Defines 8-bit variable c
|
||||||
char i, j; //Defines variables i and j
|
char hi,lo; //Defines 8-bit variables hi and lo
|
||||||
char r[7]; //Defines 8 byte array r
|
char r[7]; //Defines 8 byte array r
|
||||||
|
int addr; //Defines 16-bit variable addr
|
||||||
|
int i, j; //Defines 16-bit variables i and j
|
||||||
|
|
||||||
A function declaration consists of the function name suffixed with a (
|
A function declaration consists of the function name suffixed with a (
|
||||||
character, followed zero to three comma separated simple variables and
|
character, followed by an optional parameter set and a ) character.
|
||||||
a ) character. A function declaration terminated with a ; character is
|
|
||||||
called a forward declaration and does not generate any code, while one
|
The parameter set, if specified, may be either one to three simple
|
||||||
followed by a program block creates the specified function. Functions of
|
char variables, a single int variable, or a char variable followed
|
||||||
type char explicitly return a value (using a return statement), while
|
by an int variable.
|
||||||
functions of type void do not.
|
|
||||||
|
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 and int explicitly return one or more values
|
||||||
|
(using a return statement), while functions of type void return no
|
||||||
|
explicit value.
|
||||||
|
|
||||||
|
The return statement causes the function to exit, after which control
|
||||||
|
returns to the statement immediately following the function call. If
|
||||||
|
the last statement before the closing } of the function body is not
|
||||||
|
a return, then an implicit return is assumed.
|
||||||
|
|
||||||
|
A return statement may be followed by an list of one to three variables
|
||||||
|
following the same rules as function arguments (see FUNCTION CALLS,
|
||||||
|
below), in which case those values are returned by the function call,
|
||||||
|
otherwise the function call will not return any explicit values.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
void myfunc(); //Forward declaration of function myfunc
|
void myfunc(); //Forward declaration of function myfunc
|
||||||
|
char not(tmp) {tmp = tmp ^ $FF;}
|
||||||
|
char max(tmp1, tmp2) {if (tmp1 > tmp2) return tmp1; else return tmp2;}
|
||||||
char min(tmp1, tmp2) {if (tmp1 < tmp2) return tmp1; else return tmp2;}
|
char min(tmp1, tmp2) {if (tmp1 < tmp2) return tmp1; else return tmp2;}
|
||||||
|
char test(b,c,d) {if (b:-) return min(c,d); else return max(c,d);}
|
||||||
|
int swap(*,msb,lsb) {return *,lsb,msb;} //Swap bytes in integer
|
||||||
|
int incdec(m,i) {if (m:-) i--; else i++; return i}; //inc/dec integer
|
||||||
|
|
||||||
Note: Like all variables, function parameters are global. They must be
|
Note: Like all variables, function parameters are global. They must be
|
||||||
declared prior to the function decaration, and retain there values after
|
declared prior to the function declaration, and retain there values after
|
||||||
the function call. Although functions may be called recursively, they are
|
the function call. Although functions may be called recursively, they are
|
||||||
not re-entrant. Allocation of variables and functions is implementation
|
not re-entrant. Allocation of variables and functions is implementation
|
||||||
dependent, they could be placed in any part of memory and in any order.
|
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,
|
The default behavior is to place variables directly after the program code,
|
||||||
including them as part of the generated object file.
|
including them as part of the generated object file.
|
||||||
|
|
||||||
The return value of a function is passed through the A register. A return
|
Function arguments and return values are passed through the 6502 registers.
|
||||||
statement with an explicit expression will simply process that expression
|
Char type values are passed by loading A, Y, and X respectively, while int
|
||||||
(which leaves the result in the A register) before returning. A return
|
type values are passed by loading Y with the most significant byte and
|
||||||
statement without an expression (including an implicit return) will, by
|
X with the least significant bit.
|
||||||
default, return the value of the last processed expression.
|
|
||||||
|
A return statement without explicit return values will return whatever
|
||||||
|
happens to be in the registers at that time.
|
||||||
|
|
||||||
STRUCTS
|
STRUCTS
|
||||||
|
|
||||||
|
@ -378,19 +407,29 @@ as well as declaring struct type variables.
|
||||||
When defining a struct type, the struct keyword is followed by the name of
|
When defining a struct type, the struct keyword is followed by the name of
|
||||||
the struct type, the { character, the member definitions separated by
|
the struct type, the { character, the member definitions separated by
|
||||||
commas, and the } character. The struct definition is terminated with a
|
commas, and the } character. The struct definition is terminated with a
|
||||||
semicolon. Each member definition is composed of the optional char keyword,
|
semicolon. Each member definition is composed of a type keyword (char, int,
|
||||||
and the member name. If the member is an array, the member name is suffixed
|
or struct) and one or more member names, separated with commas. If a member
|
||||||
the [ character, the upper bound of the array, and the ] character. Each
|
is an array, the member name is suffixed the [ character, the upper bound of
|
||||||
member definition is terminated with a semicolon.
|
the array, and the ] character. Each member definition is terminated with a
|
||||||
|
semicolon. Any number of comments may appear before the first member, between
|
||||||
|
members, and after the last member.
|
||||||
|
|
||||||
When declaring a struct variable, the struct keyword is followed by the struct
|
Member names are limited to six alphanumeric characters, the first of which
|
||||||
type name, and the name of the struct variable. The struct declaration is
|
must be alphabetic. Any names are allowed including reserved words, as well
|
||||||
terminated with a semicolon.
|
as A, X, and Y (which in this case, do not refer to registers).
|
||||||
|
|
||||||
|
When declaring a struct variable, the struct keyword is followed by the
|
||||||
|
struct type name, and one or more variable names, separated with commas.
|
||||||
|
The struct declaration is terminated with a semicolon.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
struct record {char name[8]; char index; data[128];};
|
struct record {char name[8]; char index; int addr, char data[128];};
|
||||||
struct record rec;
|
struct record rec;
|
||||||
|
struct record srcrec, dstrec;
|
||||||
|
struct point {char x, y;}
|
||||||
|
struct point pnt;
|
||||||
|
struct line {struct pnt bgnpnt, endpnt;}
|
||||||
|
|
||||||
Note: Unlike simple and array variable, the members of a struct variable
|
Note: Unlike simple and array variable, the members of a struct variable
|
||||||
may not be initialized during declaration.
|
may not be initialized during declaration.
|
||||||
|
@ -412,12 +451,13 @@ a page variable. This is used to ensure that accessing an array element will
|
||||||
not cross a page boundary, which requires extra CPU cycles to execute.
|
not cross a page boundary, which requires extra CPU cycles to execute.
|
||||||
|
|
||||||
The const modifier specifies that a variable or array should not be changed
|
The const modifier specifies that a variable or array should not be changed
|
||||||
by program code. The const modifier may be preceded by the aligned modifier.
|
by program code. The const modifier may be preceded by an` aligned or
|
||||||
|
zeropage modifier.
|
||||||
|
|
||||||
A const variable declaration may include an initial value definition in
|
A const variable declaration may include an initial value definition in
|
||||||
the form of an = character and literal after the variable name.
|
the form of an = character and literal after the variable name.
|
||||||
|
|
||||||
A const array may be declared in one of two ways: the variable name
|
A const array is declared in one of two ways: the variable name
|
||||||
suffixed with a [ character, a literal specifying the upper bound of
|
suffixed with a [ character, a literal specifying the upper bound of
|
||||||
the array, and a ] character; or a variable name followed by an = character
|
the array, and a ] character; or a variable name followed by an = character
|
||||||
and string literal or series of atring and/or numeric literals separated by
|
and string literal or series of atring and/or numeric literals separated by
|
||||||
|
@ -437,20 +477,22 @@ Examples:
|
||||||
const char n = {1,2,3}; //Defines 3 byte array m containing 1, 2, and 3
|
const char n = {1,2,3}; //Defines 3 byte array m containing 1, 2, and 3
|
||||||
const char m = {"abc", 123); //Defines 5 byte array containing string and byte
|
const char m = {"abc", 123); //Defines 5 byte array containing string and byte
|
||||||
const char t = {"ab", "cd"); //Defines 6 byte array of two strings
|
const char t = {"ab", "cd"); //Defines 6 byte array of two strings
|
||||||
aligned const char fbncci[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34};
|
aligned const char fbncci = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34};
|
||||||
zeropage char ptr, tmp; //Defines zero page variables
|
zeropage char ptr, tmp; //Defines zero page variables
|
||||||
|
|
||||||
EXPRESSIONS
|
EXPRESSIONS
|
||||||
|
|
||||||
An expression is a series of one or more terms separated by operators.
|
An expression is a series of one or more terms separated by operators.
|
||||||
|
|
||||||
The first term in an expression may be a function call, subscripted array
|
Each term in an expression may be any of the following:
|
||||||
element, simple variable, literal, or register (A, X, or Y). An expression
|
function call (first term only)
|
||||||
may be preceded with a - character, in which case the first term is assumed
|
subscripted array element
|
||||||
to be a literal 0.
|
char type variable, struct member, constant, or literal
|
||||||
|
byte operation
|
||||||
|
register (A, X, or Y).
|
||||||
|
|
||||||
Additional terms are limited to subscripted array elements, simple variables,
|
An expression may be preceded with a - character, in which case the first
|
||||||
literals, and constants.
|
term is assumed to be a literal 0.
|
||||||
|
|
||||||
Operators:
|
Operators:
|
||||||
+ — Add the following value.
|
+ — Add the following value.
|
||||||
|
@ -471,10 +513,28 @@ result.
|
||||||
|
|
||||||
Note: Function calls are allowed in the first term of an expression
|
Note: Function calls are allowed in the first term of an expression
|
||||||
because upon return from the function the return value will be in the
|
because upon return from the function the return value will be in the
|
||||||
Accumulator. However, due to the 6502 having only one Accumulatorm which
|
Accumulator. However, due to the 6502 having only one Accumulator, which
|
||||||
is used for all operations between two bytes, there is no simple system
|
is used for all operations between two bytes, there is no simple system
|
||||||
agnostic method for allowing function calls in subsequent terms.
|
agnostic method for allowing function calls in subsequent terms.
|
||||||
|
|
||||||
|
BYTE OPERATIONS
|
||||||
|
|
||||||
|
Byte operation allows the the bytes in an integer value to be accessed
|
||||||
|
as individual character values. A byte operation consists of a byte
|
||||||
|
operator prefixed to an integer value.
|
||||||
|
|
||||||
|
Byte Operators:
|
||||||
|
< - Get Least Significant Byte
|
||||||
|
> - Get Most Significant Byte
|
||||||
|
|
||||||
|
The integer value may be an integer literal, an address, or an int type
|
||||||
|
variable or struct member.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
hi = >&r; lo = <&r; //Set hi, lo to MSB, LSB of address of array R
|
||||||
|
page = >53281; //Set page to MSB of the integer literal 53281
|
||||||
|
lsb = <count; //Set lsb to low byte of integer variable count
|
||||||
|
|
||||||
CONTENTIONS
|
CONTENTIONS
|
||||||
|
|
||||||
An contention is a construct which generates either TRUE or FALSE condition,
|
An contention is a construct which generates either TRUE or FALSE condition,
|
||||||
|
@ -624,7 +684,7 @@ a variable length.
|
||||||
INDEX-OF OPERATOR
|
INDEX-OF OPERATOR
|
||||||
|
|
||||||
The index-of operator ? generates a literal value equal to the offset in bytes
|
The index-of operator ? generates a literal value equal to the offset in bytes
|
||||||
of a specified stucture member. It is allowed anywhere a literal would be and
|
of a specified structure member. It is allowed anywhere a literal would be and
|
||||||
should be used anytime the offset of the member of a struct is required.
|
should be used anytime the offset of the member of a struct is required.
|
||||||
|
|
||||||
When using the size-of operator, it is prefixed to the member specification.
|
When using the size-of operator, it is prefixed to the member specification.
|
||||||
|
@ -634,7 +694,7 @@ Examples:
|
||||||
blkmem(?rec.data, &s); //Search block for segment where data contains s
|
blkmem(?rec.data, &s); //Search block for segment where data contains s
|
||||||
memcpy(?rec.data, &t); //Copy bytes of rec up to member data into t
|
memcpy(?rec.data, &t); //Copy bytes of rec up to member data into t
|
||||||
|
|
||||||
Note: The idex-of operator is evaluated at compile time and generates two
|
Note: The index-of operator is evaluated at compile time and generates two
|
||||||
bytes of machine language code. It is the most efficient method of specifying
|
bytes of machine language code. It is the most efficient method of specifying
|
||||||
a the offset of a struct member.
|
a the offset of a struct member.
|
||||||
|
|
||||||
|
@ -645,21 +705,21 @@ term in an expression. A function call consists of the function name
|
||||||
appended with a ( character, followed by zero to three arguments separated
|
appended with a ( character, followed by zero to three arguments separated
|
||||||
with commas, and a closing ) character.
|
with commas, and a closing ) character.
|
||||||
|
|
||||||
The first argument of a function call may be an expression, address, or
|
The first argument of a function call may be an expression, integer,
|
||||||
string (see below).
|
address, or string (see below).
|
||||||
|
|
||||||
The second argument may be a term (subscripted array element, simple
|
The second argument may be a term (subscripted array element, simple
|
||||||
variable, or constant), address, or string,
|
variable, or constant), integer, address, or string,
|
||||||
|
|
||||||
The third argument may only be a simple variable or constant.
|
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
|
If the first or second argument is an integer address or string, then
|
||||||
arguments may be passed.
|
no more arguments may be passed.
|
||||||
|
|
||||||
When passing the address of a variable, array, struct, or struct member
|
When passing the address of a variable, array, struct, or struct member
|
||||||
into a function, the variable specification is prefixed with the
|
into a function, the variable specification is prefixed with the
|
||||||
address-of operator &. When passing a string, the string is simply
|
address-of operator &. When passing a literal string, it is simply
|
||||||
specified as the argument with.
|
specified as is.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
c = getc(); //Get character from keyboard
|
c = getc(); //Get character from keyboard
|
||||||
|
@ -671,7 +731,7 @@ Examples:
|
||||||
puts("Hello World"); //Write "Hello World" to screen
|
puts("Hello World"); //Write "Hello World" to screen
|
||||||
memdst(&dstrec); //Set struct variable as destination
|
memdst(&dstrec); //Set struct variable as destination
|
||||||
memcpy(140, &srcrec); //Copy struct variable to destination struct
|
memcpy(140, &srcrec); //Copy struct variable to destination struct
|
||||||
puts(&rec.name); //Write struct membet to screen
|
puts(&rec.name); //Write struct member to screen
|
||||||
|
|
||||||
Note: This particular argument passing convention has been chosen because
|
Note: This particular argument passing convention has been chosen because
|
||||||
of the 6502's limited number of registers and stack processing instructions.
|
of the 6502's limited number of registers and stack processing instructions.
|
||||||
|
@ -698,14 +758,14 @@ 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
|
stack after a function call. When using a pop statement, it is followed
|
||||||
with one or more simple variables or subscripted array elements , separated
|
with one or more simple variables or subscripted array elements , separated
|
||||||
by commas, and terminated with a semicolon. If any of the arguments are to
|
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.
|
be discarded, a period may be specified instead of a variable name.
|
||||||
|
|
||||||
The number of arguments pushed and popped may or may not be the same,
|
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.
|
depending on how the machine language routine manipulates the stack pointer.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
push d,r; mult(); pop p; //multiply d times r and store in p
|
push d,r; mult(); pop p; //multiply d times r and store in p
|
||||||
push x1,y1,x2,y2; rect(); pop *,*,*,*; //draw rectangle from x1,y1 to x2,y2
|
push x1,y1,x2,y2; rect(); pop .,.,.,.; //draw rectangle from x1,y1 to x2,y2
|
||||||
push &s, "tail"; strcat(); //concatenate "tail" onto string s
|
push &s, "tail"; strcat(); //concatenate "tail" onto string s
|
||||||
push x[i],y[i]; rotate(d); pop x[i],y[i]; //rotate point x[1],y[i] by d
|
push x[i],y[i]; rotate(d); pop x[i],y[i]; //rotate point x[1],y[i] by d
|
||||||
|
|
||||||
|
@ -845,8 +905,10 @@ of code to be executed if the conditional was false.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
if (c = 27) goto end;
|
if (c = 27) goto end;
|
||||||
if (n) q = div(n,d) else puts("Division by 0!");
|
if (n) q = div(n,d) else putln("Division by 0!");
|
||||||
if (r[j]<r[i]) {t=r[i],r[i]=r[j],r[j]=t)}
|
if (r[q]<r[p]) {t=r[p],r[p]=r[q],r[q]=t)}
|
||||||
|
if (!>i | <i) puts("i is zero.");
|
||||||
|
if (>i > >j || >i = >j && <i > <j) k = i; else k = j;
|
||||||
|
|
||||||
Note: In order to optimize the compiled code, the if and else statements
|
Note: In order to optimize the compiled code, the if and else statements
|
||||||
are to 6502 relative branch instructions. This limits the amount of
|
are to 6502 relative branch instructions. This limits the amount of
|
||||||
|
@ -958,6 +1020,7 @@ if it is true, the code block is repeated.
|
||||||
Examples:
|
Examples:
|
||||||
do c = rdkey(); while (c=0); //Wait for keypress
|
do c = rdkey(); while (c=0); //Wait for keypress
|
||||||
do (c = getchr(); putchr(c); while (c<>13) //Echo line to screen
|
do (c = getchr(); putchr(c); while (c<>13) //Echo line to screen
|
||||||
|
i=0; do {i++;} while (>i <= >j && <i < <j); //Count from 0 to J
|
||||||
|
|
||||||
Note: Unlike the other loop structures do/while statements do not use
|
Note: Unlike the other loop structures do/while statements do not use
|
||||||
6502 JMP instructions. This optimizes the compiled code, but limits
|
6502 JMP instructions. This optimizes the compiled code, but limits
|
||||||
|
@ -1021,10 +1084,11 @@ The #define directive allows the definition of constants but not macros.
|
||||||
The #if, #else, and #endif directives are not recognized at all by the
|
The #if, #else, and #endif directives are not recognized at all by the
|
||||||
compiler. They may be added in the future.
|
compiler. They may be added in the future.
|
||||||
|
|
||||||
The only type recognized by the compiler is char. Since the 6502 is an
|
The only types recognized by the compiler are char and int. Int values
|
||||||
8-bit processor, multi-byte types would generate over-complicated code.
|
may only be used in limited contexts. Since the 6502 is an 8-bit processor,
|
||||||
In addition, the signed and unsigned keywords are unrecognized, due to the
|
multi-byte types would generate over-complicated code. In addition, the
|
||||||
6502's limited signed comparison functionality.
|
signed and unsigned keywords are unrecognized, due to the 6502's limited
|
||||||
|
signed comparison functionality.
|
||||||
|
|
||||||
Because of the 6502's peculiar indirect addressing modes, pointers are not
|
Because of the 6502's peculiar indirect addressing modes, pointers are not
|
||||||
currently implemented. Limited pointer operations may be implemented using
|
currently implemented. Limited pointer operations may be implemented using
|
||||||
|
|
|
@ -1,34 +1,34 @@
|
||||||
Character Symbols Recognized by the C02 Compiler
|
Character Symbols Recognized by the C02 Compiler
|
||||||
|
|
||||||
Symbol Prefix Operator Comparator Delimiter
|
Symbol Prefix/Suffix Operator Contention Other
|
||||||
! Bitwise Or Logical Not
|
! Bitwise Or Logical Not
|
||||||
" String Literal
|
" String Literal
|
||||||
# Constant
|
# Constant
|
||||||
$ Hexadecimal
|
$ Hexadecimal
|
||||||
% Binary
|
% Binary
|
||||||
& Address Of Bitwise And
|
& Address Of Bitwise And
|
||||||
' Character Literal
|
' Character Literal
|
||||||
( Comparison
|
( Contention
|
||||||
) Comparison
|
) Contention
|
||||||
* (pointer)
|
* (pointer)
|
||||||
+ Addition
|
+ Addition
|
||||||
, Declarations
|
, Argument Separator
|
||||||
- Subtraction
|
- Subtraction
|
||||||
. Struct Members
|
. Null Placeholder Struct Member Separator
|
||||||
/ Comment
|
/ Comment
|
||||||
: Status Flag Shortcut Else
|
: Status Flag Shortcut Else
|
||||||
; Statement
|
; Statement
|
||||||
< Less Than
|
< Integer LSB Less Than
|
||||||
= Equal To Assignment
|
= Equal To Assignment
|
||||||
> Greater Than
|
> Integer MSB Greater Than
|
||||||
? Index Of Shortcut If
|
? Index Of Shortcut If
|
||||||
@ Length Of
|
@ Length Of
|
||||||
[ Array Element
|
[ Array Element
|
||||||
\
|
\
|
||||||
] Array Element
|
] Array Element
|
||||||
^ (pointer)
|
^ (pointer)
|
||||||
_
|
_
|
||||||
{ Block Start
|
{ Block Start
|
||||||
| Bitwise Or
|
| Bitwise Or
|
||||||
} Block End
|
} Block End
|
||||||
~
|
~
|
||||||
|
|
|
@ -119,7 +119,7 @@ void prscnd(char trmntr, int revrse) {
|
||||||
revcmp = revrse;
|
revcmp = revrse;
|
||||||
if (look('!')) revcmp = (revcmp) ? FALSE: TRUE;
|
if (look('!')) revcmp = (revcmp) ? FALSE: TRUE;
|
||||||
DEBUG("Set REVCMP to %d\n", revcmp)
|
DEBUG("Set REVCMP to %d\n", revcmp)
|
||||||
if (!look('?')) prsxpr(0);
|
if (!look('.')) prsxpr(0);
|
||||||
if (look(':')) prsflg(revcmp); //Parse Flag Operator
|
if (look(':')) prsflg(revcmp); //Parse Flag Operator
|
||||||
else prscmp(revcmp); //Parse Comparison Operator
|
else prscmp(revcmp); //Parse Comparison Operator
|
||||||
prslop(); //Parse Logical Operator
|
prslop(); //Parse Logical Operator
|
||||||
|
|
41
src/dclrtn.c
41
src/dclrtn.c
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
int addprm(char* prmtr) {
|
int addprm(char* prmtr) {
|
||||||
reqvar(FALSE); //Get Variable Name
|
reqvar(FALSE); //Get Variable Name
|
||||||
if (varble.type == VTINT) {
|
if (vartyp == VTINT) {
|
||||||
strcpy(prmtrx, value);
|
strcpy(prmtrx, value);
|
||||||
strcpy(prmtry, value);
|
strcpy(prmtry, value);
|
||||||
strcat(prmtry, "+1");
|
strcat(prmtry, "+1");
|
||||||
|
@ -38,8 +38,8 @@ void addfnc(void) {
|
||||||
prmtry[0] = 0;
|
prmtry[0] = 0;
|
||||||
prmtrx[0] = 0;
|
prmtrx[0] = 0;
|
||||||
skpspc(); //Skip Spaces
|
skpspc(); //Skip Spaces
|
||||||
if (isalph() || match('?')) { //Parse Parameters
|
if (isalph() || match('.')) { //Parse Parameters
|
||||||
if (!look('?')) {if (addprm(prmtra)) goto addfne;} //Get First Parameter
|
if (!look('.')) {if (addprm(prmtra)) goto addfne;} //Get First Parameter
|
||||||
if (look(',')) { //Look for Comma
|
if (look(',')) { //Look for Comma
|
||||||
if (addprm(prmtry)) goto addfne; //Get Second Parameter
|
if (addprm(prmtry)) goto addfne; //Get Second Parameter
|
||||||
if (look(',')) { //Look for Comma
|
if (look(',')) { //Look for Comma
|
||||||
|
@ -85,7 +85,7 @@ void penum(int m, int bitmsk) {
|
||||||
expect('{');
|
expect('{');
|
||||||
do {
|
do {
|
||||||
if (enmval > 0xFF) ERROR("Maximum ENUM or BITMASK value exceeded\n", 0, EXIT_FAILURE)
|
if (enmval > 0xFF) ERROR("Maximum ENUM or BITMASK value exceeded\n", 0, EXIT_FAILURE)
|
||||||
if (look('?'))
|
if (look('.'))
|
||||||
DEBUG("Skipping sequence %d\n", enmval)
|
DEBUG("Skipping sequence %d\n", enmval)
|
||||||
else {
|
else {
|
||||||
getwrd(); //get defined identifier
|
getwrd(); //get defined identifier
|
||||||
|
@ -129,18 +129,33 @@ void pdecl(int m, int t) {
|
||||||
cmtlin(); //Write out declaration comment
|
cmtlin(); //Write out declaration comment
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check for and Parse Type Keyword *
|
||||||
|
* Returns: Type (enum types) */
|
||||||
|
int ctype(int reqtyp) {
|
||||||
|
if (wordis("BITMASK")) return TBITMASK;
|
||||||
|
else if (wordis("STRUCT")) return TSTRUCT;
|
||||||
|
else if (wordis("ENUM")) return TENUM;
|
||||||
|
else if (wordis("CHAR")) return TCHAR;
|
||||||
|
else if (wordis("INT")) return TINT;
|
||||||
|
else if (wordis("VOID")) return TVOID;
|
||||||
|
else if (reqtyp) ERROR("Type Declaration Expected\n", 0, EXIT_FAILURE)
|
||||||
|
return TNONE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for and Parse Type Keyword *
|
/* Check for and Parse Type Keyword *
|
||||||
* Args: m - Modifier Type */
|
* Args: m - Modifier Type */
|
||||||
int ptype(int m) {
|
int ptype(int m) {
|
||||||
int reslt = TRUE;
|
int type = ctype(FALSE);
|
||||||
if (wordis("STRUCT")) pstrct(m); //Parse 'struct' declaration
|
switch (type) {
|
||||||
else if (wordis("ENUM")) penum(m, FALSE); //Parse 'enum' declaration
|
case TSTRUCT: pstrct(m); break; //Parse 'struct' declaration
|
||||||
else if (wordis("BITMASK")) penum(m, TRUE); //Parse 'enum' declaration
|
case TENUM: penum(m, FALSE); break; //Parse 'enum' declaration
|
||||||
else if (wordis("CHAR")) pdecl(m, VTCHAR); //Parse 'char' declaration
|
case TBITMASK: penum(m, TRUE); break; //Parse 'enum' declaration
|
||||||
else if (wordis("INT")) pdecl(m, VTINT); //Parse 'int' declaration
|
case TCHAR: pdecl(m, VTCHAR); break; //Parse 'char' declaration
|
||||||
else if (wordis("VOID")) pdecl(m, VTVOID); //Parse 'void' declaration
|
case TINT: pdecl(m, VTINT); break; //Parse 'int' declaration
|
||||||
else reslt = FALSE;
|
case TVOID: pdecl(m, VTVOID); break; //Parse 'void' declaration
|
||||||
return reslt;
|
default: return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pmtype(int m) {
|
int pmtype(int m) {
|
||||||
|
|
|
@ -11,4 +11,7 @@ int prmcnt; //Number of Parameters
|
||||||
|
|
||||||
void addcon(int numval); //Add Constant
|
void addcon(int numval); //Add Constant
|
||||||
int pmodfr(); //Check for and Parse Modifier
|
int pmodfr(); //Check for and Parse Modifier
|
||||||
|
int ctype(int reqtyp); //Check for Type Keyword
|
||||||
int ptype(int m); //Check for and Parse Type Keyword
|
int ptype(int m); //Check for and Parse Type Keyword
|
||||||
|
|
||||||
|
enum types {TNONE, TVOID, TENUM, TBITMASK,TCHAR, TINT, TSTRUCT};
|
||||||
|
|
43
src/expr.c
43
src/expr.c
|
@ -37,8 +37,9 @@ void poptrm(void) {
|
||||||
void prsval(int alwreg, int alwcon) {
|
void prsval(int alwreg, int alwcon) {
|
||||||
DEBUG("Parsing value\n", 0)
|
DEBUG("Parsing value\n", 0)
|
||||||
skpspc();
|
skpspc();
|
||||||
if (islpre()) prslit(); //Parse Literal
|
if (islpre()) prslit(); //Parse Literal
|
||||||
else if (isalph()) prsvar(alwreg, alwcon); //Parse Variable
|
else if (isalph()) prsvar(alwreg, alwcon); //Parse Variable
|
||||||
|
else if (isbtop()) prsbop(); //Parse Byte Operator
|
||||||
else expctd("literal or variable");
|
else expctd("literal or variable");
|
||||||
DEBUG("Parsed value of type %d\n", valtyp)
|
DEBUG("Parsed value of type %d\n", valtyp)
|
||||||
skpspc();
|
skpspc();
|
||||||
|
@ -56,7 +57,7 @@ void prcmns(void) {
|
||||||
* "" if no index defined */
|
* "" if no index defined */
|
||||||
void prsidx(int clbrkt) {
|
void prsidx(int clbrkt) {
|
||||||
expect('[');
|
expect('[');
|
||||||
prsval(TRUE, TRUE); //Parse Value, Allowing Registers
|
prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants
|
||||||
DEBUG("Parsed array index '%s'\n", value)
|
DEBUG("Parsed array index '%s'\n", value)
|
||||||
if (clbrkt) expect(']');
|
if (clbrkt) expect(']');
|
||||||
}
|
}
|
||||||
|
@ -114,7 +115,7 @@ void chkidx(void) {
|
||||||
* Sets: term - the term (as a string) */
|
* Sets: term - the term (as a string) */
|
||||||
int prstrm(int alwint) {
|
int prstrm(int alwint) {
|
||||||
DEBUG("Parsing term\n", 0)
|
DEBUG("Parsing term\n", 0)
|
||||||
prsval(FALSE, TRUE); //Parse Term - Disallow Registers
|
prsval(FALSE, TRUE); //Parse Value - Disallow Registers, Allow Constants
|
||||||
if (valtyp == FUNCTION) ERROR("Function call only allowed in first term\n", 0, EXIT_FAILURE)
|
if (valtyp == FUNCTION) ERROR("Function call only allowed in first term\n", 0, EXIT_FAILURE)
|
||||||
strcpy(term, value);
|
strcpy(term, value);
|
||||||
if (valtyp == VARIABLE && prcvar(alwint)) return TRUE;
|
if (valtyp == VARIABLE && prcvar(alwint)) return TRUE;
|
||||||
|
@ -180,19 +181,36 @@ int chkadr(int adract, int alwstr) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parse Byte Operator */
|
||||||
|
void prsbop(void) {
|
||||||
|
char byteop = getnxt();
|
||||||
|
CCMNT(byteop);
|
||||||
|
DEBUG("Parsing byte operator '%c'\n", byteop)
|
||||||
|
if (chkadr(FALSE, FALSE)) {
|
||||||
|
sprintf(value, "%c(%s)", byteop, word);
|
||||||
|
valtyp = LITERAL;
|
||||||
|
} else {
|
||||||
|
reqvar(FALSE);
|
||||||
|
if (vartyp != VTINT) ERROR("Integer Value Expected\n", 0, EXIT_FAILURE)
|
||||||
|
if (byteop == '>') strcat(value, "+1");
|
||||||
|
vartyp = VTCHAR;
|
||||||
|
}
|
||||||
|
DEBUG("Set value to \"%s\"\n", value)
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse Function Argument or Return Values */
|
/* Parse Function Argument or Return Values */
|
||||||
void prsfpr(char trmntr) {
|
void prsfpr(char trmntr) {
|
||||||
if (!chkadr(ADLDYX, TRUE) && isxpre() || match('?')) {
|
if (!chkadr(ADLDYX, TRUE) && isxpre() || match('.')) {
|
||||||
if (!look('?')) {if (prsxpf(0)) goto prsfne;}
|
if (!look('.')) {if (prsxpf(0)) goto prsfne;}
|
||||||
if (look(',') && !chkadr(ADLDYX, TRUE)) {
|
if (look(',') && !chkadr(ADLDYX, TRUE)) {
|
||||||
if (!look('?')) {
|
if (!look('.')) {
|
||||||
if (prstrm(TRUE)) goto prsfne;
|
if (prstrm(TRUE)) goto prsfne;
|
||||||
asmlin("LDY", term);
|
asmlin("LDY", term);
|
||||||
}
|
}
|
||||||
if (look(',')) {
|
if (look(',')) {
|
||||||
prsval(FALSE, TRUE);
|
prsval(FALSE, TRUE); //Parse Value - Disallow Registers, Allow Constants
|
||||||
if (valtyp > VARIABLE) ERROR("Illegal Value Function Argument\n", 0, EXIT_FAILURE);
|
if (valtyp > VARIABLE) ERROR("Illegal Value Function Argument\n", 0, EXIT_FAILURE);
|
||||||
if (valtyp == VARIABLE && varble.type != VTCHAR) ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE);
|
if (valtyp == VARIABLE && vartyp != VTCHAR) ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE);
|
||||||
asmlin("LDX", value); }
|
asmlin("LDX", value); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,7 +242,7 @@ void prcvri(void) {
|
||||||
|
|
||||||
/* Process Variable in Term */
|
/* Process Variable in Term */
|
||||||
int prcvar(int alwint) {
|
int prcvar(int alwint) {
|
||||||
switch (varble.type) {
|
switch (vartyp) {
|
||||||
case VTINT:
|
case VTINT:
|
||||||
if (!alwint) ERROR("Illegal Use of Integer Variable %s\n", word, EXIT_FAILURE)
|
if (!alwint) ERROR("Illegal Use of Integer Variable %s\n", word, EXIT_FAILURE)
|
||||||
prcvri();
|
prcvri();
|
||||||
|
@ -258,7 +276,7 @@ int prcftm(int alwint) {
|
||||||
/* Parse first term of expession *
|
/* Parse first term of expession *
|
||||||
* First term can include function calls */
|
* First term can include function calls */
|
||||||
int prsftm(int alwint) {
|
int prsftm(int alwint) {
|
||||||
prsval(TRUE, TRUE); //Parse Value, Allowing Registers
|
prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants
|
||||||
return prcftm(alwint);
|
return prcftm(alwint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,7 +344,10 @@ void prsxpi(char trmntr) {
|
||||||
if (valtyp == FUNCTION) {
|
if (valtyp == FUNCTION) {
|
||||||
strcpy(term, value);
|
strcpy(term, value);
|
||||||
prsfnc(0); //Parse Expression Function
|
prsfnc(0); //Parse Expression Function
|
||||||
} else if (valtyp == VARIABLE && varble.type == VTINT) {
|
} else if (valtyp == STRUCTURE) {
|
||||||
|
prsmbr(value);
|
||||||
|
if (vartyp != VTINT) ERROR("Illegal Member %s In Integer Expression", value, EXIT_FAILURE)
|
||||||
|
} else if (valtyp == VARIABLE && vartyp == VTINT) {
|
||||||
prcvri(); //Process Integer Variable
|
prcvri(); //Process Integer Variable
|
||||||
} else {
|
} else {
|
||||||
ERROR("Illegal Variable %s In Integer Expression", value, EXIT_FAILURE)
|
ERROR("Illegal Variable %s In Integer Expression", value, EXIT_FAILURE)
|
||||||
|
|
|
@ -18,6 +18,7 @@ int prcftm(int alwint); //Process First Term
|
||||||
void prcvri(void); //Process Integer Variable
|
void prcvri(void); //Process Integer Variable
|
||||||
int prcvar(int alwint); //Process Variable in Term
|
int prcvar(int alwint); //Process Variable in Term
|
||||||
void prsadr(int adract); //Parse and Compile Address of Operator
|
void prsadr(int adract); //Parse and Compile Address of Operator
|
||||||
|
void prsbop(void); //Parse Byte Operator
|
||||||
void prsval(int alwreg, int alwcon); //Parse Value
|
void prsval(int alwreg, int alwcon); //Parse Value
|
||||||
void prsfnc(char trmntr); //Parse function call
|
void prsfnc(char trmntr); //Parse function call
|
||||||
void prsfpr(char trmntr); //Parse Function Paraeters or Return
|
void prsfpr(char trmntr); //Parse Function Paraeters or Return
|
||||||
|
|
|
@ -22,6 +22,7 @@ int isanum(void) {return isalnum(nxtchr);}
|
||||||
int isapos(void) {return match('\'');}
|
int isapos(void) {return match('\'');}
|
||||||
int isbin(void) {return inbtwn('0', '1');}
|
int isbin(void) {return inbtwn('0', '1');}
|
||||||
int isbpre(void) {return TF(isnpre() || isapos());}
|
int isbpre(void) {return TF(isnpre() || isapos());}
|
||||||
|
int isbtop(void) {return TF(match('<') || match('>'));}
|
||||||
int isdec(void) {return inbtwn('0', '9');}
|
int isdec(void) {return inbtwn('0', '9');}
|
||||||
int iscpre(void) {return match('#');}
|
int iscpre(void) {return match('#');}
|
||||||
int ishexd(void) {return TF(isdec() || inbtwn('A', 'Z'));}
|
int ishexd(void) {return TF(isdec() || inbtwn('A', 'Z'));}
|
||||||
|
|
|
@ -29,6 +29,7 @@ int isanum(); //Is Next Character AlphaNumeric
|
||||||
int isapos(); //Is Next Character an Apostrophe
|
int isapos(); //Is Next Character an Apostrophe
|
||||||
int isbin(); //Is Next Character a Binary Digit
|
int isbin(); //Is Next Character a Binary Digit
|
||||||
int isbpre(); //Is Next Character a Binary Prefix
|
int isbpre(); //Is Next Character a Binary Prefix
|
||||||
|
int isbtop(); //Is Next Character a Byte Operator
|
||||||
int isdec(); //Is Next Character a Decimal Digit
|
int isdec(); //Is Next Character a Decimal Digit
|
||||||
int iscpre(); //Is Next Character a Constant Prefix
|
int iscpre(); //Is Next Character a Constant Prefix
|
||||||
int ishexd(); //Is Next Character a Hexadecimal Digit
|
int ishexd(); //Is Next Character a Hexadecimal Digit
|
||||||
|
|
17
src/stmnt.c
17
src/stmnt.c
|
@ -126,8 +126,8 @@ void prcasn(char trmntr) {
|
||||||
void prcasi(char trmntr) {
|
void prcasi(char trmntr) {
|
||||||
DEBUG("Processing Integer Assignment\n", 0);
|
DEBUG("Processing Integer Assignment\n", 0);
|
||||||
expect('=');
|
expect('=');
|
||||||
strcpy(xsnvar, word); //Set Assignment LSB
|
strcpy(xsnvar, vrname); //Set Assignment LSB
|
||||||
strcpy(ysnvar, word); strcat(ysnvar, "+1"); //Set Assignment MSB
|
strcpy(ysnvar, vrname); strcat(ysnvar, "+1"); //Set Assignment MSB
|
||||||
ysnidx[0] = 0; //No Y Index
|
ysnidx[0] = 0; //No Y Index
|
||||||
prsxpi(trmntr);
|
prsxpi(trmntr);
|
||||||
prcaxy();
|
prcaxy();
|
||||||
|
@ -145,13 +145,15 @@ int getidx(char* idx) {
|
||||||
/* Process Assignment Variable(s) */
|
/* Process Assignment Variable(s) */
|
||||||
void prcavr(char trmntr) {
|
void prcavr(char trmntr) {
|
||||||
chksym(TRUE, FALSE, word);
|
chksym(TRUE, FALSE, word);
|
||||||
if (varble.type == VTINT) {
|
DEBUG("Processing assignment of variable %s\n", word);
|
||||||
if (ispopr()) {if (prspst(trmntr, TRUE, word, "")) expctd("post operator");}
|
strcpy(vrname, word); //save variable to assign to
|
||||||
|
if (valtyp == STRUCTURE) prsmbr(vrname); //Updates word and vartyp
|
||||||
|
if (vartyp == VTINT) {
|
||||||
|
if (ispopr()) {if (prspst(trmntr, TRUE, vrname, "")) expctd("post operator");}
|
||||||
else prcasi(trmntr); //Process Integer Assignment
|
else prcasi(trmntr); //Process Integer Assignment
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strcpy(asnvar, word); //save variable to assign to
|
strcpy(asnvar, vrname);
|
||||||
if (valtyp == STRUCTURE) prsmbr(asnvar);
|
|
||||||
asntyp = valtyp; //Set Assigned Variable Type
|
asntyp = valtyp; //Set Assigned Variable Type
|
||||||
DEBUG("Set STA variable to %s\n", asnvar)
|
DEBUG("Set STA variable to %s\n", asnvar)
|
||||||
if (asntyp == VARIABLE && look(';')) {
|
if (asntyp == VARIABLE && look(';')) {
|
||||||
|
@ -210,6 +212,7 @@ void pasm(void) {
|
||||||
/* Parse and Compile an Assignment */
|
/* Parse and Compile an Assignment */
|
||||||
void prsasn(char trmntr) {
|
void prsasn(char trmntr) {
|
||||||
getwrd(); //Get Variable to be Assigned
|
getwrd(); //Get Variable to be Assigned
|
||||||
|
DEBUG("Parsing assignment of word %s\n", word)
|
||||||
prcavr(trmntr);
|
prcavr(trmntr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,7 +346,7 @@ void pinlne(void) {
|
||||||
void ppop(void) {
|
void ppop(void) {
|
||||||
DEBUG("Parsing POP statement\n", 0)
|
DEBUG("Parsing POP statement\n", 0)
|
||||||
do {
|
do {
|
||||||
if (look('?')) term[0]=0;
|
if (look('.')) term[0]=0;
|
||||||
else {
|
else {
|
||||||
reqvar(TRUE);
|
reqvar(TRUE);
|
||||||
strcpy(term, value);
|
strcpy(term, value);
|
||||||
|
|
115
src/vars.c
115
src/vars.c
|
@ -14,6 +14,7 @@
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "label.h"
|
#include "label.h"
|
||||||
#include "vars.h"
|
#include "vars.h"
|
||||||
|
#include "dclrtn.h"
|
||||||
|
|
||||||
/* Lookup variable name in variable table *
|
/* Lookup variable name in variable table *
|
||||||
* Sets: varidx = index into vartbl array *
|
* Sets: varidx = index into vartbl array *
|
||||||
|
@ -24,6 +25,7 @@ int fndvar(char *name) {
|
||||||
for (varidx=0; varidx<varcnt; varidx++) {
|
for (varidx=0; varidx<varcnt; varidx++) {
|
||||||
if (strcmp(vartbl[varidx].name, name) == 0) {
|
if (strcmp(vartbl[varidx].name, name) == 0) {
|
||||||
memcpy(&varble, &vartbl[varidx], sizeof(varble));
|
memcpy(&varble, &vartbl[varidx], sizeof(varble));
|
||||||
|
vartyp = varble.type;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +51,11 @@ int fndmbr(int idx, char *name) {
|
||||||
DEBUG("Looking up member '%s'\n", word)
|
DEBUG("Looking up member '%s'\n", word)
|
||||||
for (mbridx=0; mbridx<mbrcnt; mbridx++) {
|
for (mbridx=0; mbridx<mbrcnt; mbridx++) {
|
||||||
if (membrs[mbridx].strcti != idx) continue;
|
if (membrs[mbridx].strcti != idx) continue;
|
||||||
if (strcmp(membrs[mbridx].name, name) == 0) return TRUE;
|
if (strcmp(membrs[mbridx].name, name) == 0) {
|
||||||
|
memcpy(&membr, &membrs[mbridx], sizeof(membr));
|
||||||
|
vartyp = membr.vartyp;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -84,7 +90,7 @@ void prcmbr(char* name) {
|
||||||
if (valtyp == FUNCTION) ERROR("Illegal Function Reference\n", 0, EXIT_FAILURE)
|
if (valtyp == FUNCTION) ERROR("Illegal Function Reference\n", 0, EXIT_FAILURE)
|
||||||
DEBUG("Checking for member %s", word) DETAIL(" with struct index %d\n", stcidx)
|
DEBUG("Checking for member %s", word) DETAIL(" with struct index %d\n", stcidx)
|
||||||
if (!fndmbr(stcidx, word)) ERROR("Struct does Not Contain Member %s\n", word, EXIT_FAILURE)
|
if (!fndmbr(stcidx, word)) ERROR("Struct does Not Contain Member %s\n", word, EXIT_FAILURE)
|
||||||
mbrofs += membrs[mbridx].offset; //Get Member Offet in Struct
|
mbrofs += membr.offset; //Get Member Offet in Struct
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse next word as struct member *
|
/* Parse next word as struct member *
|
||||||
|
@ -95,9 +101,9 @@ void prsmbr(char* name) {
|
||||||
mbrofs = 0;
|
mbrofs = 0;
|
||||||
stcidx = varble.stcidx; //Get Struct Index
|
stcidx = varble.stcidx; //Get Struct Index
|
||||||
prcmbr(name);
|
prcmbr(name);
|
||||||
while (membrs[mbridx].stype == STRUCTURE && nxtchr == '.') {
|
while (membr.vartyp == VTSTRUCT && nxtchr == '.') {
|
||||||
stcidx = membrs[mbridx].symidx;
|
stcidx = membr.symidx;
|
||||||
prcmbr(membrs[mbridx].name);
|
prcmbr(membr.name);
|
||||||
}
|
}
|
||||||
sprintf(word, "+$%hhX", mbrofs); //Get Member Offet in Struct
|
sprintf(word, "+$%hhX", mbrofs); //Get Member Offet in Struct
|
||||||
strcat(name, word); //Add Offset to Struct
|
strcat(name, word); //Add Offset to Struct
|
||||||
|
@ -133,8 +139,8 @@ int pidxof(void) {
|
||||||
mbridx = -1; //Set Member Index to None
|
mbridx = -1; //Set Member Index to None
|
||||||
reqvar(FALSE); //Parse Variable Name to get Size Of
|
reqvar(FALSE); //Parse Variable Name to get Size Of
|
||||||
if (mbridx > -1) {
|
if (mbridx > -1) {
|
||||||
sprintf(value, "$%hhX", membrs[mbridx].offset);
|
sprintf(value, "$%hhX", membr.offset);
|
||||||
return membrs[mbridx].offset;
|
return membr.offset;
|
||||||
}
|
}
|
||||||
ERROR("IndexOf operator requires a struct member\n", 0, EXIT_FAILURE);
|
ERROR("IndexOf operator requires a struct member\n", 0, EXIT_FAILURE);
|
||||||
return 0; //Suppress Warning
|
return 0; //Suppress Warning
|
||||||
|
@ -149,8 +155,8 @@ int psizof(void) {
|
||||||
mbridx = -1; //Set Member Index to None
|
mbridx = -1; //Set Member Index to None
|
||||||
reqvar(FALSE); //Parse Variable Name to get Size Of
|
reqvar(FALSE); //Parse Variable Name to get Size Of
|
||||||
if (mbridx > -1) {
|
if (mbridx > -1) {
|
||||||
sprintf(value, "$%hhX", membrs[mbridx].size);
|
sprintf(value, "$%hhX", membr.size);
|
||||||
return membrs[mbridx].size;
|
return membr.size;
|
||||||
}
|
}
|
||||||
if (datlen[varidx]) {
|
if (datlen[varidx]) {
|
||||||
sprintf(value, "$%hhX", datlen[varidx]);
|
sprintf(value, "$%hhX", datlen[varidx]);
|
||||||
|
@ -270,7 +276,7 @@ void addvar(int m, int t) {
|
||||||
prsnum(0xFFFF);
|
prsnum(0xFFFF);
|
||||||
else {
|
else {
|
||||||
prsvar(FALSE, FALSE);
|
prsvar(FALSE, FALSE);
|
||||||
if (t == VTINT && varble.type != t)
|
if (t == VTINT && vartyp != t)
|
||||||
ERROR("ALIAS Type Mismatch\n", 0, EXIT_FAILURE)
|
ERROR("ALIAS Type Mismatch\n", 0, EXIT_FAILURE)
|
||||||
if (t > VTINT) ERROR("Type may not be ALIASed\n", 0, EXIT_FAILURE)
|
if (t > VTINT) ERROR("Type may not be ALIASed\n", 0, EXIT_FAILURE)
|
||||||
}
|
}
|
||||||
|
@ -370,8 +376,10 @@ void wvrtbl(void) {
|
||||||
void addstc(void) {
|
void addstc(void) {
|
||||||
if (!fndstc(word)) ERROR("Undefined Struct '%s\n", word,EXIT_FAILURE)
|
if (!fndstc(word)) ERROR("Undefined Struct '%s\n", word,EXIT_FAILURE)
|
||||||
strct = strcts[stcidx]; //Retrieve Structure
|
strct = strcts[stcidx]; //Retrieve Structure
|
||||||
getwrd(); //Get Variable Name
|
do {
|
||||||
addvar(MTNONE, VTSTRUCT);
|
getwrd(); //Get Variable Name
|
||||||
|
addvar(MTNONE, VTSTRUCT);
|
||||||
|
} while (look(','));
|
||||||
expect(';');
|
expect(';');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,46 +388,63 @@ void addstc(void) {
|
||||||
void defstc(void) {
|
void defstc(void) {
|
||||||
DEBUG("Parsing struct definition\n", 0)
|
DEBUG("Parsing struct definition\n", 0)
|
||||||
if (fndstc(word)) ERROR("Duplicate Declaration of Struct '%s\n", word,EXIT_FAILURE)
|
if (fndstc(word)) ERROR("Duplicate Declaration of Struct '%s\n", word,EXIT_FAILURE)
|
||||||
|
int type;
|
||||||
int prnidx = stcidx;
|
int prnidx = stcidx;
|
||||||
strncpy(strct.name, word, STCLEN);
|
strncpy(strct.name, word, STCLEN);
|
||||||
DEBUG("Set struct name to '%s'\n", word);
|
DEBUG("Set struct name to '%s'\n", word);
|
||||||
strct.size = 0; //Initialize Struct Length
|
strct.size = 0; //Initialize Struct Length
|
||||||
while (look('/')) skpcmt(FALSE); //Skip Comments
|
while (look('/')) skpcmt(FALSE); //Skip Comments
|
||||||
do {
|
do {
|
||||||
getwrd(); //Get Member Name
|
getwrd(); //Get Next word
|
||||||
if (wordis("STRUCT")) {
|
type = ctype(TRUE); //Check if word is a type declaration
|
||||||
getwrd(); //Get Structure Name
|
switch (type) {
|
||||||
if (!fndstc(word)) ERROR("Structure '%s' Not Defined\n", word, EXIT_FAILURE)
|
case TSTRUCT:
|
||||||
membr.stype = STRUCTURE;
|
vartyp = VTSTRUCT;
|
||||||
membr.size = strcts[stcidx].size;
|
getwrd(); //Get Structure Name
|
||||||
membr.symidx = stcidx;
|
if (!fndstc(word)) ERROR("Structure '%s' Not Defined\n", word, EXIT_FAILURE)
|
||||||
getwrd(); //Get Member Name
|
mbrsiz = strcts[stcidx].size;
|
||||||
} else {
|
break;
|
||||||
if (wordis("CHAR")) getwrd(); //Skip Optional Type Declaration
|
case TINT:
|
||||||
membr.stype = VARIABLE;
|
vartyp = VTINT;
|
||||||
membr.size = 1;
|
mbrsiz = 2;
|
||||||
membr.symidx = -1;
|
stcidx = -1;
|
||||||
|
break;
|
||||||
|
case TCHAR:
|
||||||
|
vartyp = VTCHAR;
|
||||||
|
mbrsiz = 1;
|
||||||
|
stcidx = -1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ERROR("Invalid Type %s in Struct Definition\n", word, EXIT_FAILURE)
|
||||||
}
|
}
|
||||||
if (fndmbr(stccnt, word)) ERROR("Duplicate Declaration of Struct Member '%s\n", word,EXIT_FAILURE)
|
DEBUG("Parsing members of type %s\n", word)
|
||||||
DEBUG("Parsing member %s\n", word)
|
do {
|
||||||
strncpy(membr.name, word, STMLEN); //Set Member Name
|
getwrd(); //Get Member Name
|
||||||
membr.strcti = prnidx; //Set Parent Struct Index
|
DEBUG("Parsing member %s\n", word)
|
||||||
membr.offset = strct.size; //Set Offset into Struct
|
if (fndmbr(stccnt, word)) ERROR("Duplicate Declaration of Struct Member '%s\n", word,EXIT_FAILURE)
|
||||||
if (membr.stype == VARIABLE) {
|
if (strlen(word) > STMLEN) ERROR("Member Name %s too long\n", word, EXIT_FAILURE)
|
||||||
DEBUG("Checking for array definition\n", 0)
|
strcpy(membr.name, word); //Set Member Name
|
||||||
if (match('[')) {
|
membr.strcti = prnidx; //Set Parent Struct Index
|
||||||
CCMNT('[');
|
membr.vartyp = vartyp; //Set Member Variable Type
|
||||||
skpchr();
|
membr.symidx = stcidx; //Set Member Symbol Index
|
||||||
membr.stype = ARRAY;
|
membr.offset = strct.size; //Set Offset into Struct
|
||||||
DEBUG("Parsing array size\n", 0)
|
membr.size = mbrsiz; //Set Member Size
|
||||||
membr.size = prsnum(0xFF) + 1;
|
if (membr.vartyp == VTCHAR) {
|
||||||
expect(']');
|
DEBUG("Checking member for array definition\n", 0)
|
||||||
|
if (match('[')) {
|
||||||
|
CCMNT('[');
|
||||||
|
skpchr();
|
||||||
|
membr.vartyp = VTARRAY;
|
||||||
|
DEBUG("Parsing member array size\n", 0)
|
||||||
|
membr.size = prsnum(0xFF) + 1;
|
||||||
|
expect(']');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
DEBUG("Set member type to %d", membr.vartyp) DETAIL(" and size to %d\n", membr.size);
|
||||||
DEBUG("Set member type to %d", membr.stype) DETAIL(" and size to %d\n", membr.size);
|
DEBUG("Adding member at index %d\n", mbrcnt);
|
||||||
DEBUG("Adding member at index %d\n", mbrcnt);
|
membrs[mbrcnt++] = membr;
|
||||||
membrs[mbrcnt++] = membr;
|
strct.size += membr.size;
|
||||||
strct.size += membr.size;
|
} while (look(','));
|
||||||
expect(';');
|
expect(';');
|
||||||
while (look('/')) skpcmt(FALSE); //Skip Comments
|
while (look('/')) skpcmt(FALSE); //Skip Comments
|
||||||
} while (!look('}'));
|
} while (!look('}'));
|
||||||
|
@ -440,7 +465,7 @@ void logstc(void) {
|
||||||
for (mbridx=0; mbridx<mbrcnt; mbridx++) {
|
for (mbridx=0; mbridx<mbrcnt; mbridx++) {
|
||||||
membr = membrs[mbridx];
|
membr = membrs[mbridx];
|
||||||
fprintf(logfil, "%-8s %-8s", strcts[membr.strcti].name, membr.name);
|
fprintf(logfil, "%-8s %-8s", strcts[membr.strcti].name, membr.name);
|
||||||
fprintf(logfil, " %5d %5d %6d %5d\n", membr.stype, membr.symidx, membr.offset, membr.size);
|
fprintf(logfil, " %5d %5d %6d %5d\n", membr.vartyp, membr.symidx, membr.offset, membr.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ struct varrec varble; //Variable Table Entry
|
||||||
int varcnt; //Number of Variables in Table
|
int varcnt; //Number of Variables in Table
|
||||||
int varidx; //Index into Variable Tables
|
int varidx; //Index into Variable Tables
|
||||||
char vrname[MAXVAR+1]; //Variable Name
|
char vrname[MAXVAR+1]; //Variable Name
|
||||||
|
int vartyp; //Variable/Member Type
|
||||||
int vrwrtn; //Variables Written Flag
|
int vrwrtn; //Variables Written Flag
|
||||||
|
|
||||||
struct strctd { //Struct Definition
|
struct strctd { //Struct Definition
|
||||||
|
@ -32,7 +33,7 @@ int stcidx; //Index into Struct Tables
|
||||||
struct membrd { //Struct Membetr Definition
|
struct membrd { //Struct Membetr Definition
|
||||||
char name[STMLEN+1]; //Member Name
|
char name[STMLEN+1]; //Member Name
|
||||||
int strcti; //Parent Struct Index
|
int strcti; //Parent Struct Index
|
||||||
int stype; //Member Symbol Type
|
int vartyp; //Member Symbol Type
|
||||||
int symidx; //Member Symbol Index
|
int symidx; //Member Symbol Index
|
||||||
int offset; //Offset into Struct
|
int offset; //Offset into Struct
|
||||||
int size; //Member Size
|
int size; //Member Size
|
||||||
|
@ -43,6 +44,7 @@ struct membrd membr; //Defined Member
|
||||||
int mbrcnt; //Number of Struct Members Defined
|
int mbrcnt; //Number of Struct Members Defined
|
||||||
int mbridx; //Index into Struct Member Tables
|
int mbridx; //Index into Struct Member Tables
|
||||||
int mbrofs; //Member Offset
|
int mbrofs; //Member Offset
|
||||||
|
int mbrsiz; //Member Size
|
||||||
|
|
||||||
enum vtypes {VTVOID, VTREG, VTCHAR, VTINT, VTARRAY, VTSTRUCT}; //Variable Types
|
enum vtypes {VTVOID, VTREG, VTCHAR, VTINT, VTARRAY, VTSTRUCT}; //Variable Types
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**********************************************
|
/*********************************
|
||||||
* STRINGS - Demonstrate string.h02 functions *
|
* STRUCTS - Test C02 structures *
|
||||||
**********************************************/
|
*********************************/
|
||||||
|
|
||||||
//Specify System Header using -H option
|
//Specify System Header using -H option
|
||||||
#include <stddef.h02>
|
#include <stddef.h02>
|
||||||
|
@ -16,60 +16,64 @@ int yx;
|
||||||
|
|
||||||
//Define Structure
|
//Define Structure
|
||||||
struct record { /* Sample Record */
|
struct record { /* Sample Record */
|
||||||
char name[8]; //Name
|
char name[8]; //Name
|
||||||
char index; //Index
|
char index; //Index
|
||||||
data[128]; //Data
|
int addr; //Address
|
||||||
|
char data[128]; //Data
|
||||||
};
|
};
|
||||||
|
|
||||||
//Declare Structure Variable
|
//Declare Structure Variable
|
||||||
struct record srcrec;
|
struct record srcrec;
|
||||||
struct record dstrec;
|
struct record dstrec;
|
||||||
|
|
||||||
//Struct Containing Structs
|
//Structs Containing Structs
|
||||||
struct point { char xpos; char ypos; };
|
struct point {char x, y; };
|
||||||
struct point pnt;
|
struct point pnt;
|
||||||
struct rect {struct point toplft; struct point btmrgt; };
|
|
||||||
|
struct rect {struct point toplft, btmrgt; };
|
||||||
struct rect box;
|
struct rect box;
|
||||||
struct frame {struct rect outer; struct rect inner; };
|
|
||||||
|
struct frame {struct rect outer, inner; };
|
||||||
struct frame fram;
|
struct frame fram;
|
||||||
|
|
||||||
main:
|
main:
|
||||||
|
|
||||||
//Set Structure Members
|
//Set Structure Members
|
||||||
strdst(&srcrec.name); strcpy("RECNAME");
|
strdst(srcrec.name); strcpy("RECNAME");
|
||||||
srcrec.index = 1;
|
srcrec.index = 1;
|
||||||
|
srcrec.addr = &srcrec;
|
||||||
for (i = 0; i<=@srcrec.data; i++)
|
for (i = 0; i<=@srcrec.data; i++)
|
||||||
srcrec.data[i] = i;
|
srcrec.data[i] = i;
|
||||||
|
|
||||||
//Clear Destination Record
|
//Clear Destination Record
|
||||||
memclr(@dstrec,&dstrec);
|
memclr(@dstrec, dstrec);
|
||||||
prtdst();
|
prtdst();
|
||||||
|
|
||||||
//Copy Source Record into Destination Record
|
//Copy Source Record into Destination Record
|
||||||
memdst(&dstrec);
|
memdst(dstrec);
|
||||||
memcpy(@srcrec, &srcrec);
|
memcpy(@srcrec, srcrec);
|
||||||
|
|
||||||
prtdst();
|
prtdst();
|
||||||
|
|
||||||
//Clear Box
|
//Clear Box
|
||||||
memclr(@box, &box); //Clear Box Members
|
memclr(@box, box); //Clear Box Members
|
||||||
prtbox(); //Print Box Members
|
prtbox(""); //Print Box Members
|
||||||
|
|
||||||
//Set Box Members
|
//Set Box Members
|
||||||
box.toplft.xpos=1; box.toplft.ypos=2;
|
box.toplft.x=1; box.toplft.y=2;
|
||||||
box.btmrgt.xpos=8; box.btmrgt.ypos=9;
|
box.btmrgt.x=8; box.btmrgt.y=9;
|
||||||
prtbox();
|
prtbox("");
|
||||||
newlin();
|
newlin();
|
||||||
|
|
||||||
//Clear Frame
|
//Clear Frame
|
||||||
memclr(@fram, &fram); //Clear Frame Members
|
memclr(@fram, fram); //Clear Frame Members
|
||||||
prtfrm(); //Print Frame Members
|
prtfrm(); //Print Frame Members
|
||||||
|
|
||||||
//Set Frame Members
|
//Set Frame Members
|
||||||
fram.outer.toplft.xpos=10; fram.outer.toplft.ypos=11;
|
fram.outer.toplft.x=10; fram.outer.toplft.y=11;
|
||||||
fram.outer.btmrgt.xpos=98; fram.outer.btmrgt.ypos=99;
|
fram.outer.btmrgt.x=98; fram.outer.btmrgt.y=99;
|
||||||
fram.inner.toplft.xpos=22; fram.inner.toplft.ypos=23;
|
fram.inner.toplft.x=22; fram.inner.toplft.y=23;
|
||||||
fram.inner.btmrgt.xpos=86; fram.inner.btmrgt.ypos=87;
|
fram.inner.btmrgt.x=86; fram.inner.btmrgt.y=87;
|
||||||
prtfrm();
|
prtfrm();
|
||||||
newlin();
|
newlin();
|
||||||
|
|
||||||
|
@ -77,8 +81,9 @@ goto exit;
|
||||||
|
|
||||||
//Print Destination Record
|
//Print Destination Record
|
||||||
void prtdst() {
|
void prtdst() {
|
||||||
setdst(&dstrec.name); printf("REC.NAME=\"%s\"%n");
|
setdst(dstrec.name); printf("REC.NAME=\"%s\"%n");
|
||||||
printf(dstrec.index, "REC.INDEX=%d%n");
|
printf(dstrec.index, "REC.INDEX=%d%n");
|
||||||
|
setdst(dstrec.addr); printf("REC.ADDR=$%w%n");
|
||||||
puts("REC.DATA=[");
|
puts("REC.DATA=[");
|
||||||
for (i = 0; i<@dstrec.data; i++) {
|
for (i = 0; i<@dstrec.data; i++) {
|
||||||
if (i) putc(',');
|
if (i) putc(',');
|
||||||
|
@ -90,26 +95,26 @@ void prtdst() {
|
||||||
|
|
||||||
//Print Frame
|
//Print Frame
|
||||||
void prtfrm() {
|
void prtfrm() {
|
||||||
putln("OUTER."); cpybox(&fram.outer); prtbox();
|
cpybox(fram.outer); prtbox("OUTER.");
|
||||||
putln("INNER."); cpybox(&fram.inner); prtbox();
|
cpybox(fram.inner); prtbox("INNER.");
|
||||||
anykey();
|
anykey();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpybox() {
|
void cpybox() {
|
||||||
savrxy(); setdst(&box);
|
savrxy(); setdst(box);
|
||||||
resrxy(); memcpy(@box);
|
resrxy(); memcpy(@box);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Print Box
|
//Print Box
|
||||||
void prtbox() {
|
void prtbox(yx) {
|
||||||
puts(" TOPLFT."); prtpnt(&box.toplft);
|
puts(yx); puts("TOPLFT."); prtpnt(box.toplft);
|
||||||
puts(" BTMRGT."); prtpnt(&box.btmrgt);
|
puts(yx); puts("BTMRGT."); prtpnt(box.btmrgt);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Print Point
|
//Print Point
|
||||||
void prtpnt() {
|
void prtpnt() {
|
||||||
savrxy(); setdst(&pnt);
|
savrxy(); setdst(pnt);
|
||||||
resrxy(); memcpy(@pnt);
|
resrxy(); memcpy(@pnt);
|
||||||
printf(pnt.xpos,"XPOS=%d,");
|
printf(pnt.x,"X=%d,");
|
||||||
printf(pnt.ypos,"YPOS=%d%n");
|
printf(pnt.y,"Y=%d%n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#pragma zeropage $80
|
#pragma zeropage $80
|
||||||
|
|
||||||
char b,d;
|
char b,d;
|
||||||
|
char hi,lo;
|
||||||
char s[128];
|
char s[128];
|
||||||
char aa,yy,xx;
|
char aa,yy,xx;
|
||||||
|
|
||||||
|
@ -15,6 +16,9 @@ int i,j;
|
||||||
int m,n;
|
int m,n;
|
||||||
int yx;
|
int yx;
|
||||||
|
|
||||||
|
hi = >c; lo = <c;
|
||||||
|
hi = >&c; lo = <&c;
|
||||||
|
|
||||||
i<<;
|
i<<;
|
||||||
j>>;
|
j>>;
|
||||||
m++;
|
m++;
|
||||||
|
@ -31,13 +35,13 @@ d = fnd(b,c);
|
||||||
i = fni(c);
|
i = fni(c);
|
||||||
j = fnj(b,c);
|
j = fnj(b,c);
|
||||||
|
|
||||||
int fnb(?,yy,xx) {
|
int fnb(.,yy,xx) {
|
||||||
return ?,xx,yy;
|
return .,xx,yy;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fnd(aa,yy,xx) {
|
int fnd(aa,yy,xx) {
|
||||||
if (aa) return ?,xx,yy;
|
if (aa) return .,xx,yy;
|
||||||
else return ?,yy,xx;
|
else return .,yy,xx;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fni(yx) {
|
int fni(yx) {
|
||||||
|
|
|
@ -3,41 +3,77 @@
|
||||||
#pragma origin 1000
|
#pragma origin 1000
|
||||||
|
|
||||||
char d, i;
|
char d, i;
|
||||||
|
char lo, hi;
|
||||||
char index, name[8], data[128];
|
char index, name[8], data[128];
|
||||||
|
int addr;
|
||||||
|
|
||||||
//Define Structure
|
//Define Structures
|
||||||
struct record {
|
struct point {
|
||||||
char name[8];
|
char x, y;
|
||||||
char index;
|
|
||||||
char data[128];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Declare Structure Variable
|
struct line {
|
||||||
|
struct point bgnpnt, endpnt;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct record {
|
||||||
|
/* This is a Record */ //Extra Comment
|
||||||
|
char name[8]; //Name
|
||||||
|
char index; //Index
|
||||||
|
int addr; //Address
|
||||||
|
struct point pnt; //Point
|
||||||
|
char data[128]; //Data
|
||||||
|
};
|
||||||
|
|
||||||
|
//Declare Structure Variables
|
||||||
|
struct point pnt;
|
||||||
|
struct point bgnpnt, endpnt;
|
||||||
|
struct line lin;
|
||||||
struct record rec;
|
struct record rec;
|
||||||
|
|
||||||
//Display Structure Info
|
//Display Structure Info
|
||||||
|
printf(?pnt.x,"?pnt.x=%d\t");
|
||||||
|
printf(@pnt.x,"@pnt.x=%d\n");
|
||||||
|
printf(?pnt.y,"?pnt.y=%d\t");
|
||||||
|
printf(@pnt.y,"@pnt.y=%d\n");
|
||||||
|
|
||||||
printf(@rec,"@rec=%d\n");
|
printf(@rec,"@rec=%d\n");
|
||||||
printf(?rec.name,"?rec.name=%d\t");
|
printf(?rec.name,"?rec.name=%d\t");
|
||||||
printf(@rec.name,"@rec.name=%d\n");
|
printf(@rec.name,"@rec.name=%d\n");
|
||||||
printf(?rec.index,"?rec.index=%d\t");
|
printf(?rec.index,"?rec.index=%d\t");
|
||||||
printf(@rec.index,"@rec.index=%d\n");
|
printf(@rec.index,"@rec.index=%d\n");
|
||||||
|
printf(?rec.addr,"?rec.addr=%d\t");
|
||||||
|
printf(@rec.addr,"@rec.addr=%d\n");
|
||||||
|
printf(?rec.pnt,"?rec.pnt=%d\t");
|
||||||
|
printf(@rec.pnt,"@rec.pnt=%d\n");
|
||||||
printf(?rec.data,"?rec.data=%d\t");
|
printf(?rec.data,"?rec.data=%d\t");
|
||||||
printf(@rec.data,"@rec.data=%d\n");
|
printf(@rec.data,"@rec.data=%d\n");
|
||||||
|
|
||||||
|
//Get Member LSB & MSB
|
||||||
|
hi = >rec.addr; lo = <rec.addr;
|
||||||
|
hi = >&rec.data; lo = <&rec.data;
|
||||||
|
|
||||||
//Set Structure Members
|
//Set Structure Members
|
||||||
strdst(&rec.name); strcpy(name);
|
strdst(&rec.name); strcpy(name);
|
||||||
rec.index = index;
|
rec.index = index;
|
||||||
|
rec.addr = $ABCD;
|
||||||
|
rec.pnt.x = 33;
|
||||||
|
rec.pnt.y = 44;
|
||||||
for (i = 0; i<=128; i++)
|
for (i = 0; i<=128; i++)
|
||||||
rec.data[i] = d;
|
rec.data[i] = d;
|
||||||
|
|
||||||
//Pass Entire Structure into Function
|
//Pass Entire Structure into Function
|
||||||
blkput(@rec, &rec);
|
blkput(@rec, &rec);
|
||||||
|
|
||||||
|
//Print Structure Members
|
||||||
|
setdst(rec.name); putln("rec.name=\"%s\"");
|
||||||
|
|
||||||
//Copy Struct Member
|
//Copy Struct Member
|
||||||
memdst(&data); memcpy(@rec.data, &rec.data);
|
memdst(&data); memcpy(@rec.data, &rec.data);
|
||||||
|
|
||||||
//Get Structure Members
|
//Get Structure Members
|
||||||
index = rec.index;
|
index = rec.index;
|
||||||
|
addr = rec.addr;
|
||||||
for (i = 0; i<129; i++)
|
for (i = 0; i<129; i++)
|
||||||
d = rec.data[i];
|
d = rec.data[i];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user