mirror of
https://github.com/RevCurtisP/C02.git
synced 2024-06-08 06:29:32 +00:00
Merge branch 'master' into x16vera
This commit is contained in:
commit
4da225525b
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -24,4 +24,7 @@ output
|
||||||
|
|
||||||
#Deprecated Files
|
#Deprecated Files
|
||||||
*/oldclude
|
*/oldclude
|
||||||
*/*.zip
|
*/*.zip
|
||||||
|
|
||||||
|
#Private Directories
|
||||||
|
notes
|
3
Makefile
3
Makefile
|
@ -4,5 +4,6 @@ mainfile=src/c02.c
|
||||||
outfile=c02
|
outfile=c02
|
||||||
c02: ${incfiles} ${mainfile}
|
c02: ${incfiles} ${mainfile}
|
||||||
gcc ${gccopts} ${incfiles} ${mainfile} -o ${outfile}
|
gcc ${gccopts} ${incfiles} ${mainfile} -o ${outfile}
|
||||||
|
gcc ${gccopts} a02.h a02.c -o a02
|
||||||
clean:
|
clean:
|
||||||
rm ${outfile}
|
rm ${outfile} a02
|
||||||
|
|
68
README.md
68
README.md
|
@ -43,7 +43,6 @@ but it may not be in a working state.
|
||||||
#pragma origin 8192 //Set start address of object code
|
#pragma origin 8192 //Set start address of object code
|
||||||
#pragma zeropage $80 //Set start address of zero page variables
|
#pragma zeropage $80 //Set start address of zero page variables
|
||||||
|
|
||||||
|
|
||||||
/* Constants */
|
/* Constants */
|
||||||
#define TRUE = $FF ; //Constants
|
#define TRUE = $FF ; //Constants
|
||||||
#define FALSE = 0
|
#define FALSE = 0
|
||||||
|
@ -54,50 +53,63 @@ struct record {char name[8]; char index;}; //Struct Definition
|
||||||
struct record rec; //Struct Declaration
|
struct record rec; //Struct Declaration
|
||||||
|
|
||||||
/* Variables and Array Declarations */
|
/* Variables and Array Declarations */
|
||||||
char i, j; //Variables
|
char b, c, d, e, f, g, h; //8-bit Variables
|
||||||
zeropage p,q; //Variables in zeropage
|
int i, j; //16-bit Variables
|
||||||
const char nine = 9; //Const variable set to decimal literal
|
zeropage char p, q; //8-bit Variables in Page 0
|
||||||
const char maxsiz = $FF; //Const variable set to hexadecimal literal
|
zeropage int u, v; //16-bit Variables in Page 0
|
||||||
const char flag = %01010101; //Const variable set to binary literal
|
const char nine = 9; //Const 8-bit variable set to decimal literal
|
||||||
const char debug = #TRUE; //Const variable set to constant
|
const char maxsiz = $FF; //Const 8-bit variable set to hexadecimal literal
|
||||||
char r[7]; //8 byte array 0 (decimal dimension)
|
const char flag = %01010101; //Const 8-bit variable set to binary literal
|
||||||
|
const char debug = #TRUE; //Const 8-bit variable set to constant
|
||||||
|
const int k = $1234; //Const 16-bit variable set to hexadecimal literal
|
||||||
|
char r[7]; //8 byte Array (decimal dimension)
|
||||||
aligned char m[$FF]; //256 byte array aligned to page boundary
|
aligned char m[$FF]; //256 byte array aligned to page boundary
|
||||||
|
const char n = {1,2,3}; //Const array set to literal list
|
||||||
const char s = "string"; //Const array set to string literal
|
const char s = "string"; //Const array set to string literal
|
||||||
const char m = {1,2,3}; //Const array set to literal list
|
|
||||||
const char t = {"one", 1); //Const array set to mixed list
|
const char t = {"one", 1); //Const array set to mixed list
|
||||||
|
|
||||||
/* Functions Declarations */
|
/* Functions Declarations */
|
||||||
void myfunc(); //Forward declaration of function
|
void myfunc(); //Forward declaration of function
|
||||||
char myfunp(tmp1, tmp2, tmp3) {
|
char fnc(c) { /*function body */} //One 8-bit Parameter
|
||||||
//function code
|
char fnd(c,d) { /*function body */} //Two 8-bit Parameters
|
||||||
}
|
char fne(c,d,e) { /*function body */} //Three 8-bit Parameters
|
||||||
|
char fni(i) { /*function body */} //One 16-bit Parameter
|
||||||
|
char fnj(c,i) { /*function body */} //8-bit and 16-bit Parameters
|
||||||
|
|
||||||
|
/* Returning from a Function */
|
||||||
|
return c, d, e; //Return up to three 8-bit values
|
||||||
|
return c,j; //Return an 8-bit an 16-bit value
|
||||||
|
return i; //Return a 16-bit value
|
||||||
|
return; //No explicit return values
|
||||||
|
|
||||||
/* Assignments */
|
/* Assignments */
|
||||||
hmove; s80vid; //Implicit Assignments
|
hmove; s80vid; //Implicit Assignments
|
||||||
x = 0; y = a; a = 1; //Register Assignments
|
x = 0; y = a; a = 1; //Register Assignments
|
||||||
b = c + d - e & f | g ^ h; //Assignment and Expression
|
b = c + d - e & f | g ^ h; //Assignment and Expression
|
||||||
r[i] = s[j+1] & t[k-1]; //Array Indexing
|
r[f] = m[g+1] & t[h-1]; //Array Indexing
|
||||||
d[j] = r[a] + s[x] + t[y]; //Arrays Indexed by Register
|
r[j] = r[a] + s[x] + t[y]; //Arrays Indexed by Register
|
||||||
r = (i>j) ? d[i] : e[j]; //Shortcut If
|
d = (e>f) ? d[e] : e[f]; //Shortcut If
|
||||||
a<< ;b[i]>>; x++; y--; //Post-Operations
|
b<< ;c[d]>>; x++; y--; //Post-Operations
|
||||||
|
|
||||||
/* Function Calls */
|
/* Function Calls */
|
||||||
i = abs(n); j = min(b,c), plot(h,v,c); //Up to Three Char Arguments
|
b = abs(c); d = min(e,f), plot(b,c,d); //Up to Three Char Arguments
|
||||||
q = div(m+n,d)) - t; n = mult(e+f, z); //Expression in First Arg Only
|
b = div(c+d,e)) - f; c = mult(d+e, f); //Expression in First Arg Only
|
||||||
puts("string"); fputs(fp, &line); //Passing Strings and Arrays
|
j = swap(i); j = ishift(b, i); //Pass Int or Char with Int
|
||||||
setdst(&dst); n = strcpy(&src); //Using Multiple String Agruments
|
puts("string"); fputs(f, &s); //Passing Strings and Arrays
|
||||||
c = getc(); setptr(*,addrhi,addrlo); //No and Skipped Arguments
|
setdst(&r); b = strcpy(&s); //Using Multiple String Arguments
|
||||||
row,col = scnpos(); i,j,k = get3d(); //Plural Assignments
|
proc(@record, &record); //Pass Length and Address of Struct
|
||||||
push d,r; mult(); pop p; //Pass Arguments via Stack
|
c = getc(); setptr(?,g,h); //No Args and Skipped Arguments
|
||||||
iprint(); inline "Hello World"; //Pass Inline String Argument
|
b,c = scnpos(); d,e,f = get3d(); //Plural Assignments
|
||||||
irect(); inline 10,10,100,100; //Pass Inline Char Arguments
|
push b,c; mult(); pop p; //Pass Arguments via Stack
|
||||||
icpstr(); inline &dst, &src; //Pass Inline Address Arguments
|
iprint(); inline "Hello World"; //Pass Inline String Argument
|
||||||
|
irect(); inline 10,10,100,100; //Pass Inline Char Arguments
|
||||||
|
icpstr(); inline &r, &s; //Pass Inline Address Arguments
|
||||||
|
|
||||||
/* Control Structures */
|
/* Control Structures */
|
||||||
if (c = 27) goto end;
|
if (c = 27) goto end;
|
||||||
if (n) q = div(n,d) else puts("Division by 0!");
|
if (b) e = div(f,g) else puts("Division by 0!");
|
||||||
if (b==0 || b>10 && b<20) fprint(n,"input %d in range");
|
if (b==0 || b>10 && b<20) fprint(n,"input %d in range");
|
||||||
c = 'A' ; while (c <= 'Z') { putc(c); c++; }
|
c = 'A' ; while (c <= 'Z') { putc(c); c++; }
|
||||||
while() { c=rdkey; if (c=0) continue; putchr(c); if (c=13) break; }
|
while() { c=rdkey; if (c=0) continue; putchr(c); if (c=13) break; }
|
||||||
do c = rdkey(); while (c=0);
|
do c = rdkey(); while (c=0);
|
||||||
do {c = getchr(); putchr(c);} while (c<>13)
|
do {c = getchr(); putchr(c);} while (c<>13)
|
||||||
|
|
724
a02.c
Normal file
724
a02.c
Normal file
|
@ -0,0 +1,724 @@
|
||||||
|
/* Simple 6502 Assembler *
|
||||||
|
* for C02 Compiler *
|
||||||
|
* Uses DASM Syntax but *
|
||||||
|
* supports 65C02 Op Codes */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "a02.h"
|
||||||
|
|
||||||
|
#define DEBUG FALSE
|
||||||
|
int debug; //Ouput Debug Info
|
||||||
|
|
||||||
|
enum otypes {BINFIL, PRGFIL}; //Object File Types
|
||||||
|
|
||||||
|
char objtyp; //Object File Type
|
||||||
|
int orgadr; //Origin Address
|
||||||
|
int curadr; //Current Address
|
||||||
|
int lstadr; //List Address
|
||||||
|
|
||||||
|
struct sym {int block; char name[MAXLBL+1]; int bytes, value, refrd;};
|
||||||
|
struct sym symbol; //Current Symbol
|
||||||
|
struct sym symtbl[MAXSYM]; //Global Symbol Table
|
||||||
|
int symcnt; //Number of Global Labels
|
||||||
|
int blknum; //Local Label Block Number (0 = Global)
|
||||||
|
|
||||||
|
char label[MAXSTR]; //Assembly Line Label
|
||||||
|
char mnmnc[MAXSTR]; //Opcode Mnemonic
|
||||||
|
char oprnd[MAXSTR]; //Opcode Mnemonic
|
||||||
|
char cmmnt[MAXSTR]; //Assembly Line Comment
|
||||||
|
char mcode[MAXSTR]; //Generated Bytes
|
||||||
|
char strng[MAXSTR]; //Parsed String
|
||||||
|
|
||||||
|
int opridx; //Index into Operand
|
||||||
|
|
||||||
|
unsigned char token, opmod; //OpCode Token, Modifier
|
||||||
|
unsigned int amode; //Addressing Modes
|
||||||
|
int zpage, opval; //ZeroPage Flag, Operand Value
|
||||||
|
|
||||||
|
char hexadr[6]; //Current Address in Hexadecimal
|
||||||
|
char bytstr[5]; //String Representation of Byte
|
||||||
|
|
||||||
|
char inplin[MAXSTR]; //Input Buffer
|
||||||
|
char *linptr; //Pointer into Input Buffer
|
||||||
|
int lineno; //Input File Line Number
|
||||||
|
int savlno; //Line Number (Saved)
|
||||||
|
|
||||||
|
int passno; //Assembler Pass Number (1 or 2)
|
||||||
|
int endasm; //End Assembly Flag
|
||||||
|
|
||||||
|
char prgnam[256]; //Assembler Path and Name (from Command Line)
|
||||||
|
char inpnam[256]; //Input File Name
|
||||||
|
char outnam[256]; //Output File Name
|
||||||
|
char lstnam[256]; //List File Name
|
||||||
|
char incnam[256]; //Include File Name
|
||||||
|
FILE *inpfil; //Input File Pointer
|
||||||
|
FILE *outfil; //Output File Pointer
|
||||||
|
FILE *lstfil; //List File Pointer
|
||||||
|
FILE *incfil; //Include File Pointer
|
||||||
|
|
||||||
|
/* Print Usage Info and Exit */
|
||||||
|
void usage(char* appnam) {
|
||||||
|
printf("Usage: %s [opts] asmfile objfile [lstfile]\n", appnam);
|
||||||
|
printf(" Opts: -p - Commodore PRG format\n");
|
||||||
|
printf(" -d - Output Debug Info\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print Error Message and Exit */
|
||||||
|
void xerror(char* format, char *s) {
|
||||||
|
if (lineno) fprintf(stderr, "%04d: ", lineno);
|
||||||
|
fprintf(stderr, format, s);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open File with Error Checking */
|
||||||
|
FILE * opnfil(char* name, char* mode) {
|
||||||
|
if (debug) printf("Opening file '%s' with mode '%s'\n", name, mode);
|
||||||
|
FILE *fp = fopen(name, mode);
|
||||||
|
if (!fp) xerror("Error Opening File '%s'\n", name);
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip Character in Input Line *
|
||||||
|
* Args: c - Character to Skip *
|
||||||
|
* Updates: linptr */
|
||||||
|
int skpchr(char c) {
|
||||||
|
if (*linptr == c) {linptr++; return TRUE;}
|
||||||
|
else return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip Spaces in Input Line *
|
||||||
|
* Updates: linptr */
|
||||||
|
void skpspc(void) {
|
||||||
|
while (*linptr && *linptr <= ' ') linptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse Word from Input Line *
|
||||||
|
* Args: skip - Skip Spaces Flag *
|
||||||
|
* *word - Buffer for Word *
|
||||||
|
* Updates: linptr *
|
||||||
|
* Returns: Word Found (TRUE/FALSE) */
|
||||||
|
int pword(int skip, char* word) {
|
||||||
|
int wrdlen = 0;
|
||||||
|
if (skip) skpspc();
|
||||||
|
while (isalnum(*linptr) || *linptr == '_') {
|
||||||
|
word[wrdlen++] = toupper(*linptr);
|
||||||
|
linptr++;
|
||||||
|
}
|
||||||
|
word[wrdlen] = 0; //Terminate String
|
||||||
|
if (wrdlen) return TRUE; else return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sym *fndsym(int block, char* name) {
|
||||||
|
for (int i=0; i < symcnt; i++) {
|
||||||
|
if (symtbl[i].block != block || strcmp(symtbl[i].name,name)) continue;
|
||||||
|
return &symtbl[i];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Symbol Value and Size */
|
||||||
|
void setsym(int value, int bytes) {
|
||||||
|
if (debug) printf("Setting Symbol %s to %d\n", symbol.name, value);
|
||||||
|
symbol.value = value;
|
||||||
|
if (bytes) symbol.bytes = bytes;
|
||||||
|
else symbol.bytes = (value > 0xFF) ? 2 : 1;
|
||||||
|
symbol.refrd = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add Character to Beginning of String */
|
||||||
|
void pfxstr(char c, char* s) {
|
||||||
|
for (int i=strlen(s)+1; i; i--)
|
||||||
|
s[i] = s[i-1]; //Copy All Characters to the Right
|
||||||
|
s[0] = c; //Insert Character at Beginning
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse Label from Input Line
|
||||||
|
* Sets: label
|
||||||
|
* Updates: linptr
|
||||||
|
* Returns: Label Found (TRUE/FALSE) */
|
||||||
|
int plabel(void) {
|
||||||
|
if (debug) puts("Parsing Label");
|
||||||
|
int block = (skpchr('.')) ? blknum : 0; //Local Label Block Number
|
||||||
|
int found = pword(FALSE, label); //Parse Word without Skipping Spaces
|
||||||
|
if (debug) {
|
||||||
|
if (found) printf("Found Label %s\n", label);
|
||||||
|
else puts("No Label Found");
|
||||||
|
}
|
||||||
|
skpchr(':'); //Skip Optional Label Terminator
|
||||||
|
if (found && passno == 1) {
|
||||||
|
if (label[0] && fndsym(block, label)) xerror("Duplicate Label %s Encountered\n", label);
|
||||||
|
if (debug) printf("Initializing Symbol %s\n", label);
|
||||||
|
symbol.block = block;
|
||||||
|
if (strlen(label) > MAXLBL) xerror("Label %s Too Long\n", label);
|
||||||
|
strcpy(symbol.name, label);
|
||||||
|
setsym(curadr, 0);
|
||||||
|
}
|
||||||
|
if (block) pfxstr('.', label);
|
||||||
|
skpspc(); //Skip to Mnemonic, Comment, or EOL
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy Character to Operand and Increment */
|
||||||
|
int cpychr(int c) {
|
||||||
|
if (c && toupper(*linptr) != c) return FALSE;
|
||||||
|
if (opridx < MAXSTR) oprnd[opridx++] = toupper(*linptr);
|
||||||
|
linptr++;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Evaluate Binary Number */
|
||||||
|
int evlbin() {
|
||||||
|
int result = 0;
|
||||||
|
cpychr('%');
|
||||||
|
while (isdigit(*linptr)) {
|
||||||
|
if (*linptr > '1') break;
|
||||||
|
result = (result << 1) + *linptr - '0';
|
||||||
|
cpychr(0);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Evaluate Binary Number */
|
||||||
|
int evlchr() {
|
||||||
|
int result = 0;
|
||||||
|
cpychr('\'');
|
||||||
|
result = *linptr;
|
||||||
|
cpychr(0);
|
||||||
|
cpychr('\'');
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Evaluate Decimal Number */
|
||||||
|
int evldec() {
|
||||||
|
int result = 0;
|
||||||
|
while (isdigit(*linptr)) {
|
||||||
|
result = result * 10 + *linptr - '0';
|
||||||
|
cpychr(0);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Evaluate Hexadecimal Number */
|
||||||
|
int evlhex() {
|
||||||
|
int result = 0;
|
||||||
|
cpychr('$');
|
||||||
|
while (isxdigit(*linptr)) {
|
||||||
|
int digit = *linptr - '0';
|
||||||
|
if (digit > 9) digit = digit - 7;
|
||||||
|
result = (result << 4) + digit;
|
||||||
|
cpychr(0);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Evaluate Symbol */
|
||||||
|
struct sym *evlsym() {
|
||||||
|
char name[MAXSTR];
|
||||||
|
int block = (cpychr('.')) ? blknum : 0;
|
||||||
|
pword(TRUE, name);
|
||||||
|
for (int i=0; name[i]; i++) if (opridx<MAXSTR) oprnd[opridx++] = name[i];
|
||||||
|
struct sym *result = fndsym(block, name);
|
||||||
|
if (passno == 2 && result == NULL) xerror("Undefined Symbol %s\n", name);
|
||||||
|
if (result) result->refrd = TRUE; //Symbol was Referenced
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Evaluate Term in Operand */
|
||||||
|
int evltrm() {
|
||||||
|
int result;
|
||||||
|
skpspc();
|
||||||
|
if (isalpha(*linptr) || *linptr == '.') {
|
||||||
|
struct sym *target = evlsym();
|
||||||
|
result = (target) ? target->value : 0x100;
|
||||||
|
}
|
||||||
|
else if (isdigit(*linptr))
|
||||||
|
result = evldec();
|
||||||
|
else switch(*linptr) {
|
||||||
|
case '$': result = evlhex(); break;
|
||||||
|
case '%': result = evlbin(); break;
|
||||||
|
case '\'': result = evlchr(); break;
|
||||||
|
default: result = -1;
|
||||||
|
}
|
||||||
|
skpspc();
|
||||||
|
if (debug) printf("Term Evaluated to %d\n", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Evaluate Operand */
|
||||||
|
int evlopd(int maxsiz) {
|
||||||
|
int result = 0;
|
||||||
|
int hilo = 0; //Return LSB (1) or MSB (2)
|
||||||
|
int prns; //Optional Parenthesis after Hi/Low Operator
|
||||||
|
if (debug) puts("Evaluating Operand");
|
||||||
|
skpspc();
|
||||||
|
if (cpychr('<')) hilo = 1;
|
||||||
|
else if (cpychr('>')) hilo = 2;
|
||||||
|
if (hilo) prns = cpychr('(');
|
||||||
|
result = evltrm();
|
||||||
|
if (result >= 0)
|
||||||
|
while (cpychr('+')) {
|
||||||
|
int opdval = evltrm();
|
||||||
|
if (opdval < 0) break;
|
||||||
|
result += opdval;
|
||||||
|
}
|
||||||
|
if (hilo) {
|
||||||
|
if (result < 0) xerror("Hi/Low Operator Requires Operand", "");
|
||||||
|
if (prns) cpychr(')'); //
|
||||||
|
switch (hilo) {
|
||||||
|
case 1: result = result & 0xFF; break; //LSB
|
||||||
|
case 2: result = result >> 8; break; //MSB
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug) printf("Operand Evaluated to %d\n", result);
|
||||||
|
if (result > maxsiz) xerror("Operand Value too Large\n", "");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write Byte to Output File */
|
||||||
|
void outbyt(int b) {
|
||||||
|
if (curadr > -1) curadr++;
|
||||||
|
if (passno != 2) return;
|
||||||
|
fputc(b & 0xFF, outfil);
|
||||||
|
sprintf(bytstr, "%02X ", b);
|
||||||
|
if (strlen(mcode) < 9) strcat(mcode, bytstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write Word to Output File */
|
||||||
|
void outwrd(int w) {
|
||||||
|
outbyt(w & 0xff);
|
||||||
|
outbyt(w >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lookup Opcode */
|
||||||
|
int lkpopc(struct opc opl[]) {
|
||||||
|
if (debug) printf("Looking up Mnemonic %s\n", mnmnc);
|
||||||
|
token = 0xFF; //Set Token to Invalid
|
||||||
|
char mne[5]; strncpy(mne, mnmnc, 4); mne[4] = 0; //Truncate Mnemonic to Four Characters
|
||||||
|
for (int i=0; opl[i].name[0]; i++) {
|
||||||
|
if (strcmp(opl[i].name, mne)) continue;
|
||||||
|
token = opl[i].token;
|
||||||
|
amode = opl[i].amode;
|
||||||
|
if (debug) printf("Found token %02X, amode %04X\n", token, amode);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble BYTE Pseudo-Op */
|
||||||
|
void asmbyt(void) {
|
||||||
|
if (debug) puts("Assembling BYTE Pseudo-Op");
|
||||||
|
do {
|
||||||
|
if (cpychr('"')) { //String Operand
|
||||||
|
while (!cpychr('"')) {outbyt(*linptr); cpychr(0); }
|
||||||
|
skpspc();
|
||||||
|
} else
|
||||||
|
outbyt(evlopd(0xFF)); //Evaluate Operand
|
||||||
|
} while (cpychr(','));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble HEX Pseudo-Op */
|
||||||
|
void asmhex(void) {
|
||||||
|
if (debug) puts("Assembling HEX Pseudo-Op");
|
||||||
|
do {outbyt(evlhex(0xFF)); } while (cpychr(','));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble WORD Pseudo-Op */
|
||||||
|
void asmwrd(void) {
|
||||||
|
do {
|
||||||
|
outwrd(evlopd(0xFFFF)); //Evaluate Operand
|
||||||
|
} while (cpychr(','));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble FILL Pseudo-Op */
|
||||||
|
void asmaln(void) {
|
||||||
|
if (debug) puts("Assembling ALIGN Pseudo-Op");
|
||||||
|
int size = evlopd(0xFFFF); if (size < 2) return;
|
||||||
|
if (debug) printf("Aligning to %d Bytes\n", size);
|
||||||
|
int fill = size - (curadr % size); if (fill == size) return;
|
||||||
|
if (debug) printf("Filling %d Bytes\n", fill);
|
||||||
|
for (int i=0; i<fill; i++) outbyt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble FILL Pseudo-Op */
|
||||||
|
void asmfll(void) {
|
||||||
|
if (debug) puts("Assembling FILL Pseudo-Op");
|
||||||
|
int size = evlopd(0xFFFF);
|
||||||
|
if (debug) printf("Filling %d Bytes\n", size);
|
||||||
|
for (int i=0; i<size; i++) outbyt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble EQU Pseudo-Op */
|
||||||
|
void asmequ(void) {
|
||||||
|
if (label[0] == 0) xerror("EQUate without Label", 0);
|
||||||
|
setsym(evlopd(0xFFFF), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble ORG Pseudo-Op */
|
||||||
|
void asmorg(void) {
|
||||||
|
orgadr = evlopd(0xFFFF);
|
||||||
|
if (passno == 1 && symbol.name[0]) {
|
||||||
|
symbol.value = orgadr;
|
||||||
|
symbol.bytes = 2;
|
||||||
|
}
|
||||||
|
if (passno == 2 && objtyp == PRGFIL)
|
||||||
|
outwrd(orgadr);
|
||||||
|
curadr = orgadr;
|
||||||
|
lstadr = orgadr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble PROCESSOR Pseudo-Op */
|
||||||
|
void asmprc(void) {
|
||||||
|
skpspc();
|
||||||
|
while (isalnum(*linptr)) cpychr(0);
|
||||||
|
if (debug) printf("Ignoring Operand %s\n", oprnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble SUBROUTINE Pseudo-Op */
|
||||||
|
void asmsub(void) {
|
||||||
|
blknum++;
|
||||||
|
sprintf(oprnd, "%d", blknum); opridx = strlen(oprnd);
|
||||||
|
if (debug) printf("Block Number set to %s\n", oprnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble INCLUDE Pseudo-Op */
|
||||||
|
void asminf(void) {
|
||||||
|
int incidx = 0;
|
||||||
|
if (debug) puts("Assembling INCLUDE Pseudo-Op");
|
||||||
|
if (incfil) xerror("Nested INCLUDE not Allowed", "");
|
||||||
|
if (!cpychr('"')) xerror("File Name Must be Quoted", "");
|
||||||
|
while (*linptr && !cpychr('"')) {
|
||||||
|
char c = *linptr; if (c == '/') c = '\\'; //Reverse Slashes for DOS/Windows
|
||||||
|
incnam[incidx++] = c;
|
||||||
|
cpychr(0);
|
||||||
|
}
|
||||||
|
incnam[incidx] = 0; //Terminate Include Name
|
||||||
|
if (incidx == 0) xerror("INCLUDE requires file name\n", "");
|
||||||
|
if (debug) printf("Include File Set to Name to '%s'\n", incnam);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble END Pseudo-Op */
|
||||||
|
void asmend(void) {
|
||||||
|
endasm = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble Pseudo-Op */
|
||||||
|
int asmpso(int dot) {
|
||||||
|
if (lkpopc(psolst) == FALSE && dot == FALSE) return FALSE;
|
||||||
|
skpspc();
|
||||||
|
if (debug) printf("Assembling Pseudo-Op %s, Token '%c'\n", mnmnc, token);
|
||||||
|
switch (token) {
|
||||||
|
case '=': asmequ(); break; //EQU
|
||||||
|
case 'B': asmbyt(); break; //BYTE
|
||||||
|
case 'H': asmhex(); break; //BYTE
|
||||||
|
case 'W': asmwrd(); break; //WORD
|
||||||
|
case 'F': asmfll(); break; //FILL
|
||||||
|
case 'S': asmsub(); break; //SUBRoutine
|
||||||
|
case 'I': asminf(); break; //INCLude
|
||||||
|
case '*': asmorg(); break; //ORG
|
||||||
|
case 'P': asmprc(); break; //PROCessor
|
||||||
|
case 'E': asmend(); break; //END
|
||||||
|
case 'A': asmaln(); break; //ALIGn
|
||||||
|
default: xerror("Undefined Pseudo-Op %s\n", mnmnc);
|
||||||
|
}
|
||||||
|
if (dot) pfxstr('.', mnmnc);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for Valid Addressing Mode */
|
||||||
|
int chkmod(int mode) {
|
||||||
|
char* s = NULL; //Pointer to Addressing Mode Description
|
||||||
|
for (int i=0; amdesc[i].amode; i++)
|
||||||
|
if (amdesc[i].amode == mode) {s = amdesc[i].desc; break;}
|
||||||
|
if (debug) printf("Checking Addressing Mode %s, %04X against %04X\n", s, mode, amode);
|
||||||
|
if (mode & amode) return TRUE;
|
||||||
|
xerror("Invalid Addressing Mode %s", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble Branch Opcode */
|
||||||
|
void asmbrn(int setzp) {
|
||||||
|
int offset = 0;
|
||||||
|
int ofsadj = (setzp) ? 2 : 3; //Offset Adjustment
|
||||||
|
if (debug) printf("Assembling Branch Opcode Token 0x%02X\n", token);
|
||||||
|
zpage = setzp;
|
||||||
|
if (isalpha(*linptr) || *linptr =='.') {
|
||||||
|
struct sym *target = evlsym();
|
||||||
|
if (target) offset = (target->value - curadr - ofsadj);
|
||||||
|
}
|
||||||
|
else if (cpychr('+')) offset = evlopd(0xFF);
|
||||||
|
else if (cpychr('-')) offset = -evlopd(0xFF);
|
||||||
|
else {
|
||||||
|
opval = evlopd(0xFFFF);
|
||||||
|
if (opval < 0) xerror("Illegal Branch Operand\n", "");
|
||||||
|
offset = opval - curadr - 2;
|
||||||
|
}
|
||||||
|
if (debug) printf("Calculated Branch Offset of %d\n", offset);
|
||||||
|
if ((offset > 127 || offset < -128) && passno == 2)
|
||||||
|
xerror("Branch Out of Range\n", "");
|
||||||
|
if (debug) printf("Branch Offset %d\n", offset);
|
||||||
|
opval = offset & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble Zero Page, Relative Opcode */
|
||||||
|
void asmzpr(void) {
|
||||||
|
int bitno = -1;
|
||||||
|
if (debug) printf("Assembling ZeroPage (Relative) Opcode Token 0x%02X\n", token);
|
||||||
|
if (strlen(mnmnc) < 4) {opmod = evlopd(7) << 4; cpychr(','); skpspc();} //Set Modifier to Bit Position
|
||||||
|
int zpval = evlopd(0xFF); cpychr(','); skpspc();//Get ZeroPage Operand
|
||||||
|
if (zpval < 0) xerror ("Instruction %s requires Multiple Operands\n", mnmnc);
|
||||||
|
if (amode == 0x0004) {zpage = TRUE; opval = zpval;} //RMB, SMB - Zero Page Operand
|
||||||
|
else {asmbrn(FALSE); opval = opval << 8 | zpval;} //BBR, BBS - Combine Operanda
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble Immediate Mode Instruction */
|
||||||
|
void asmimd(void) {
|
||||||
|
if (debug) printf("Assembling Immediate Opcode Token 0x%02X\n", token);
|
||||||
|
opval = evlopd(0xFF);
|
||||||
|
zpage = TRUE;
|
||||||
|
opmod = 0x08; //Immediate
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble Indirect Mode Instruction */
|
||||||
|
void asmind(void) {
|
||||||
|
if (debug) puts("Assembling Indirect Mode Instruction");
|
||||||
|
zpage = TRUE; opval = evlopd(0xFFFF);
|
||||||
|
if (cpychr(',') && cpychr('X') && chkmod(INDCX)) cpychr(')'); ////(Indirect,X) opmod=0
|
||||||
|
else if (cpychr(')')) {
|
||||||
|
if (cpychr(',') && cpychr('Y') && chkmod(INDCY)) opmod = 0x10; //(Indirect),Y
|
||||||
|
else if (chkmod(INDCT)) opmod = 0x11; //(Indirect)
|
||||||
|
if (token == 0x4C) zpage = FALSE; //JMP (Indirect Absolute)
|
||||||
|
}
|
||||||
|
else chkmod(0); //Illegal Addressing Mode
|
||||||
|
if (zpage && opval > 0x00FF) xerror("Operand Value too Large\n", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble Implied/Accumulator/Absolute/ZeroPage Mode Instruction */
|
||||||
|
void asmiaz(void) {
|
||||||
|
opval = evlopd(0xFFFF);
|
||||||
|
if (opval < 0) {
|
||||||
|
if (amode != IMPLD) //Implied
|
||||||
|
if (chkmod(ACMLT)) opmod = 0x08; //Accumulator
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (debug) printf("Assembling Absolute/ZeroPage 0x%02X\n", token);
|
||||||
|
zpage = (opval <= 0xff) ? TRUE : FALSE;
|
||||||
|
if (zpage && chkmod(ZPAGE)) opmod = 0x04; //ZeroPage
|
||||||
|
else if (chkmod(ABSLT)) opmod = 0x0C; //Absolute
|
||||||
|
if (cpychr(',')) {
|
||||||
|
if (cpychr('X')) {
|
||||||
|
if (zpage && chkmod(ZPAGX)) opmod = 0x14; //ZeroPage,X
|
||||||
|
else if (chkmod(ABSLX)) opmod = 0x1C; //Absolute,X
|
||||||
|
} else if (cpychr('Y')) {
|
||||||
|
if (zpage && (token == 0x82 || token == 0xA2))
|
||||||
|
opmod = 0x14; //ZeroPage,Y
|
||||||
|
else {zpage = FALSE; opmod = 0x18;} //Absolute,Y
|
||||||
|
} else chkmod(0); //Illegal Addressing Mode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fix Opcode (if needed) */
|
||||||
|
unsigned char fixopc(void) {
|
||||||
|
if (debug) printf("Fixing OpCode $%02X+$%02X\n", token, opmod);
|
||||||
|
for (int i=0; opfix[i].token; i++)
|
||||||
|
if (opfix[i].token == token && opfix[i].opmod == opmod)
|
||||||
|
return opfix[i].opcode;
|
||||||
|
return token + opmod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ouput Opcode debug Info */
|
||||||
|
void dbgopc(void) {
|
||||||
|
printf("token=$%02X, opmod=$%02X, Address Mode: ", token, opmod);
|
||||||
|
if (amode == 0x1004) puts("ZeroPage, Relative");
|
||||||
|
else if (amode == 0x0004) puts("ZeroPage");
|
||||||
|
else switch (opmod) {
|
||||||
|
case 0x00: if (amode == IMPLD) puts("Implied"); else puts("(Indirect,X)"); break;
|
||||||
|
case 0x08: if (opval < 0) puts("Accumulator"); else puts("#Immediate"); break;
|
||||||
|
case 0x10: puts("(Indirect),Y"); break;
|
||||||
|
case 0x11: puts("(Indirect)"); break;
|
||||||
|
case 0x04: puts("ZeroPage"); break;
|
||||||
|
case 0x0C: puts("Absolute"); break;
|
||||||
|
case 0x14: if ((token == 0x82 || token == 0xA2)) puts("ZeroPage,Y");
|
||||||
|
else puts("ZeroPage,X"); break;
|
||||||
|
case 0x1C: puts("Absolute,X"); break;
|
||||||
|
case 0x18: puts("Absolute,Y"); break;
|
||||||
|
default: puts("UNKOWN");
|
||||||
|
}
|
||||||
|
if (opval < 0) puts("No Operand");
|
||||||
|
else {
|
||||||
|
printf("Operand Value %d, ", opval);
|
||||||
|
if (zpage) puts("Zero Page"); else puts("Absolute");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble Opcode */
|
||||||
|
int asmopc(int dot) {
|
||||||
|
opmod = 0;
|
||||||
|
if (asmpso(dot)) return TRUE; //Check For/Assemble Pseudo-Op
|
||||||
|
if (lkpopc(opclst) == FALSE) xerror("Invalid Mnemonic %s\n", mnmnc);
|
||||||
|
if (debug) printf("Assembling Opcode Token 0x%02X, ", token);
|
||||||
|
if (debug) printf("Addressing Mode Mask 0x%04X\n", amode);
|
||||||
|
skpspc();
|
||||||
|
if (amode == RELTV) asmbrn(TRUE); //Branch (Relative) Instruction
|
||||||
|
else if (amode == 0x0004 || amode == 0x1004) asmzpr(); //Branch (Relative) Instruction
|
||||||
|
else if (cpychr('#')) asmimd(); //Assemble Implied Instruction
|
||||||
|
else if (cpychr('(')) asmind(); //Assemble Indirect Instruction
|
||||||
|
else asmiaz(); //Assemble Implied/Accumulator/Absolute/ZeroPage Instruction
|
||||||
|
if (debug) dbgopc();
|
||||||
|
int opcode = fixopc();
|
||||||
|
if (debug) printf("Writing OpCode $%02X\n", opcode);
|
||||||
|
outbyt(opcode);
|
||||||
|
if (debug) printf("Writing %s Operand %d\n", zpgabs[-zpage], opval);
|
||||||
|
if (opval >= 0) {
|
||||||
|
if (zpage) outbyt(opval); //Byte Operand
|
||||||
|
else outwrd(opval); //Word Operand
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse Opcode Mnemonic from Input Line
|
||||||
|
* Sets: mnmnc
|
||||||
|
* Updates: linptr
|
||||||
|
* Returns: Label Found (TRUE/FALSE) */
|
||||||
|
int pmnmnc(void) {
|
||||||
|
if (debug) puts("Parsing Mnemonic");
|
||||||
|
int dot = cpychr('.'); //Optional Dot before Pseudo-Op
|
||||||
|
int found = pword(TRUE, mnmnc);
|
||||||
|
opridx = 0; //Initialize Operand Index
|
||||||
|
if (found) asmopc(dot);
|
||||||
|
oprnd[opridx] = 0; //Terminate Operand String
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse Comment from Input Line
|
||||||
|
* Sets: cmmnt
|
||||||
|
* Updates: linptr */
|
||||||
|
void pcmmnt(void) {
|
||||||
|
skpspc();
|
||||||
|
int i = 0;
|
||||||
|
while (*linptr >= ' ') cmmnt[i++] = *linptr++;
|
||||||
|
cmmnt[i] = 0; //Terminate Comment
|
||||||
|
if (debug) {if (i) printf("Comment: %s\n", cmmnt); else puts("No Comment Found");}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add Label to Symbol Table */
|
||||||
|
void addsym() {
|
||||||
|
if (symbol.value<0) xerror("Origin Not Set", "");
|
||||||
|
memcpy(&symtbl[symcnt++], &symbol, sizeof(symbol));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Open Include File */
|
||||||
|
void opninc(void) {
|
||||||
|
if (debug) printf("Opening Include File %s\n", incnam);
|
||||||
|
if (lstfil) fputs("\n", lstfil);
|
||||||
|
incfil = opnfil(incnam, "r");
|
||||||
|
savlno = lineno;
|
||||||
|
lineno = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close Include File */
|
||||||
|
void clsinc(void) {
|
||||||
|
if (debug) printf("Closing Include File %s\n", incnam);
|
||||||
|
if (lstfil) fputs("\n", lstfil);
|
||||||
|
fclose(incfil);
|
||||||
|
incfil = NULL;
|
||||||
|
incnam[0] = 0;
|
||||||
|
lineno = savlno;
|
||||||
|
endasm = FALSE; //Clear End Flag for Return to Maun File
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assemble Input File (Two Pass) *
|
||||||
|
* Args: pass - Assembly Pass (1 or 2) *
|
||||||
|
* Requires: inpfil - Input File Pointer *
|
||||||
|
* Uses: inplin - Input Line Buffer *
|
||||||
|
* lineno - Input File Line Number */
|
||||||
|
void asmfil(int pass) {
|
||||||
|
endasm = FALSE; //Reset End Assembly Flag
|
||||||
|
passno = pass; //Assembly Pass Number
|
||||||
|
if (debug) printf("Assembling Pass %d\n", pass);
|
||||||
|
lineno = 1; //Initialize Input File Line Number
|
||||||
|
blknum = 1; //Initialize Local Block Number
|
||||||
|
orgadr = -1; //Origin Address Not Set
|
||||||
|
curadr = orgadr; //Set Current Address to Origin
|
||||||
|
if (debug) printf("Rewinding Input File\n");
|
||||||
|
rewind(inpfil); //Start at Beginning of Input File
|
||||||
|
while (TRUE) {
|
||||||
|
if (incfil) linptr = fgets(inplin, MAXSTR, incfil);
|
||||||
|
else linptr = fgets(inplin, MAXSTR, inpfil);
|
||||||
|
if (endasm || linptr == NULL) {if (incfil) {clsinc(); continue;} else break;}
|
||||||
|
if (debug) printf("%05d %04X: %s", lineno, curadr, inplin);
|
||||||
|
lstadr = curadr; //Set List Address
|
||||||
|
mcode[0] = 0; //Clear Generated Macbine Code
|
||||||
|
plabel(); //Parse Label
|
||||||
|
pmnmnc(); //Parse Mnemonic
|
||||||
|
pcmmnt(); //Parse Comment
|
||||||
|
if (passno == 1 && label[0]) addsym(); //Add Label to Table
|
||||||
|
if (passno == 2) {
|
||||||
|
if (lstadr < 0) hexadr[0] = 0; else sprintf(hexadr, "%04X", lstadr);
|
||||||
|
fprintf(lstfil, "%05d %-4s %-9s%-7s %-5s %-16s %s\n", lineno, hexadr, mcode, label, mnmnc, oprnd, cmmnt );
|
||||||
|
fflush(lstfil); //Flush Output Buffer in case of Segmentation Fault
|
||||||
|
}
|
||||||
|
lineno++;
|
||||||
|
if (incnam[0] && incfil == NULL) opninc(); //Open Include File
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print Symbol Table */
|
||||||
|
void prtsym(void) {
|
||||||
|
fprintf(lstfil, "\n%s Symbol Table\nBlock Name Size Value Rfd\n", "Global");
|
||||||
|
for (int i=0; i<symcnt; i++) {
|
||||||
|
int refrd = (symtbl[i].refrd) ? '*' : ' ';
|
||||||
|
fprintf(lstfil, "%5d %-8s %4d %5d %c \n", symtbl[i].block, symtbl[i].name, symtbl[i].bytes, symtbl[i].value, refrd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse Command Line Option */
|
||||||
|
int pcoptn(char *argval) {
|
||||||
|
if (argval[0] != '-') return FALSE;
|
||||||
|
char option = toupper(argval[1]);
|
||||||
|
if (debug) printf(" Option '%c'\n", option);
|
||||||
|
switch(option) {
|
||||||
|
case 'D': debug = TRUE; break; //Enable debug Output
|
||||||
|
case 'P': objtyp = PRGFIL; break; //Commodore PRG File
|
||||||
|
default: xerror("Illegal Command Line Option %s\n", argval);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse Command Line Arguments */
|
||||||
|
void pcargs(int argc, char *argv[]) {
|
||||||
|
int argnum = 0;
|
||||||
|
for (int arg = 0; arg<argc; arg++) {
|
||||||
|
if (debug) printf("Arg %d='%s'\n", arg, argv[arg]);
|
||||||
|
if (arg == 0) {strcpy(prgnam, argv[arg]); continue;}
|
||||||
|
if (pcoptn(argv[arg])) continue;
|
||||||
|
switch (argnum++) {
|
||||||
|
case 0: strcpy(inpnam, argv[arg]); break;
|
||||||
|
case 1: strcpy(outnam, argv[arg]); break;
|
||||||
|
case 2: strcpy(lstnam, argv[arg]); break;
|
||||||
|
default: xerror("Too Many Arguments\n", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (argnum<2) usage(argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
debug = DEBUG; //Initialize Debug Flag
|
||||||
|
lstnam[0] = 0; lstfil = NULL; //Default to No List File
|
||||||
|
incnam[0] = 0; incfil = NULL; //Include File Not Opened
|
||||||
|
lineno = 0; //No Line Number (yet)
|
||||||
|
objtyp = BINFIL; //Default Object File Type to Binary
|
||||||
|
pcargs(argc, argv); //Parse Command Line Arguments
|
||||||
|
inpfil = opnfil(inpnam, "r"); //Open Input File
|
||||||
|
outfil = opnfil(outnam, "wb"); //Open Output File
|
||||||
|
if (lstnam[0]) //If List File Name Specified
|
||||||
|
lstfil = opnfil(lstnam, "w"); // Open List File
|
||||||
|
asmfil(1); //Assemble Input File (First Pass)
|
||||||
|
asmfil(2); //Assemble Input File (First Pass)
|
||||||
|
if (lstfil && symcnt) prtsym(); //Print Symbol Table
|
||||||
|
exit(0); //Exit with No Errors
|
||||||
|
}
|
||||||
|
|
115
a02.h
Normal file
115
a02.h
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/* Definitions for A02 Assembler */
|
||||||
|
|
||||||
|
#define MAXSTR 128 //Maximum String Length
|
||||||
|
#define MAXLBL 8 //Maximum Symbol Length
|
||||||
|
#define MAXSYM 1024 //Maximum Number of Global Labels
|
||||||
|
|
||||||
|
#define FALSE 0
|
||||||
|
#define TRUE -1
|
||||||
|
|
||||||
|
/* Address Mode Bit Masks */
|
||||||
|
#define ACMLT 0x0001 //Accumulator [$xA]
|
||||||
|
#define IMMDT 0x0002 //*Immediate [w/Acc]
|
||||||
|
#define ZPAGE 0x0004 //Zero Page
|
||||||
|
#define ZPAGX 0x0008 //*Zero Page,X
|
||||||
|
//#define ZPAGY 0x0010 //*Zero Page,Y [By OpCodes]
|
||||||
|
#define ABSLT 0x0020 //Absolute
|
||||||
|
#define ABSLX 0x0040 //*Absolute,X [fixops()]
|
||||||
|
#define ABSLY 0x0080 //Absolute,Y
|
||||||
|
#define IMPLD 0x0100 //*Implied [x0001]
|
||||||
|
#define INDCT 0x0200 //(Indirect)
|
||||||
|
#define INDCX 0x0400 //(Indirect,X)
|
||||||
|
#define INDCY 0x0800 //(Indirect),Y
|
||||||
|
#define RELTV 0x1000 //Relative
|
||||||
|
|
||||||
|
char zpgabs[][] = {"Absolute", "ZeroPage"};
|
||||||
|
|
||||||
|
struct amd {int amode; char desc[12];};
|
||||||
|
struct amd amdesc[] = {
|
||||||
|
{ACMLT, "Accumulator"},
|
||||||
|
{IMMDT, "Immediate"},
|
||||||
|
{ZPAGE, "Zero Page"},
|
||||||
|
{ZPAGX, "Zero Page,X"},
|
||||||
|
{ABSLT, "Absolute"},
|
||||||
|
{ABSLX, "Absolute,X"},
|
||||||
|
{ABSLY, "Absolute,Y"},
|
||||||
|
{IMPLD, "Implied"},
|
||||||
|
{INDCT, "(Indirect)"},
|
||||||
|
{INDCX, "(Indirect,X)"},
|
||||||
|
{INDCY, "(Indirect),Y"},
|
||||||
|
{RELTV, "Relative"},
|
||||||
|
{0, ""}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct opc {char name[5], token; int amode;};
|
||||||
|
struct opc psolst[] = {
|
||||||
|
{"BYTE", 'B', 0}, {"HEX", 'H'}, {"WORD", 'W', 0}, {"EQU", '=', 0}, {"FILL", 'F', 0},
|
||||||
|
{"INCL", 'I', 0}, {"SUBR", 'S', 0}, {"DC", 'B', 0}, {"DS", 'F', 0}, {"ALIG", 'A', 0},
|
||||||
|
{"ORG", '*', 0}, {"PROC", 'P', 0}, {"END", 'E', 0}, {"", 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct opc opclst[] = {
|
||||||
|
{"BRK", 0x00, 0x0100}, {"NOP", 0xEA, 0x0100}, {"STP", 0xDB, 0x0100}, {"WAI", 0xCB, 0x0100},
|
||||||
|
{"DEX", 0xCA, 0x0100}, {"DEY", 0x88, 0x0100}, {"INX", 0xE8, 0x0100}, {"INY", 0xC8, 0x0100},
|
||||||
|
{"PHA", 0x48, 0x0100}, {"PHP", 0x08, 0x0100}, {"PHX", 0xDA, 0x0100}, {"PHY", 0x5A, 0x0100},
|
||||||
|
{"PLA", 0x68, 0x0100}, {"PLP", 0x28, 0x0100}, {"PLX", 0xFA, 0x0100}, {"PLY", 0x7A, 0x0100},
|
||||||
|
{"CLC", 0x18, 0x0100}, {"CLD", 0xD8, 0x0100}, {"CLI", 0x58, 0x0100}, {"CLV", 0xB8, 0x0100},
|
||||||
|
{"SEC", 0x38, 0x0100}, {"SED", 0xF8, 0x0100}, {"SEI", 0x78, 0x0100},
|
||||||
|
{"TAX", 0xAA, 0x0100}, {"TAY", 0xA8, 0x0100}, {"TSX", 0xBA, 0x0100},
|
||||||
|
{"TXA", 0x8A, 0x0100}, {"TYA", 0x98, 0x0100}, {"TXS", 0x9A, 0x0100},
|
||||||
|
{"RTI", 0x40, 0x0100}, {"RTS", 0x60, 0x0100},
|
||||||
|
|
||||||
|
{"BCS", 0xB0, 0x1000}, {"BEQ", 0xF0, 0x1000}, {"BMI", 0x30, 0x1000}, {"BVS", 0x70, 0x1000},
|
||||||
|
{"BCC", 0x90, 0x1000}, {"BNE", 0xD0, 0x1000}, {"BPL", 0x10, 0x1000}, {"BVC", 0x50, 0x1000},
|
||||||
|
{"BRA", 0x80, 0x1000},
|
||||||
|
|
||||||
|
{"LDA", 0xA1, 0x0EFE}, {"ADC", 0x61, 0x0EFE}, {"AND", 0x21, 0x0EFE}, {"CMP", 0xC1, 0x0EFE},
|
||||||
|
{"STA", 0x81, 0x0EFE}, {"SBC", 0xE1, 0x0EFE}, {"ORA", 0x01, 0x0EFE}, {"EOR", 0x41, 0x0EFE},
|
||||||
|
|
||||||
|
{"ASL", 0x02, 0x007D}, {"ROL", 0x22, 0x007D}, {"INC", 0xE2, 0x007D}, {"LSR", 0x42, 0x007D},
|
||||||
|
{"ROR", 0x62, 0x007D}, {"DEC", 0xC2, 0x007D},
|
||||||
|
|
||||||
|
{"RMB0", 0x07, 0x0004}, {"RMB1", 0x17, 0x0004}, {"RMB2", 0x27, 0x0004}, {"RMB3", 0x37, 0x0004},
|
||||||
|
{"RMB4", 0x47, 0x0004}, {"RMB5", 0x57, 0x0004}, {"RMB6", 0x67, 0x0004}, {"RMB7", 0x77, 0x0004},
|
||||||
|
{"SMB0", 0x87, 0x0004}, {"SMB1", 0x97, 0x0004}, {"SMB2", 0xA7, 0x0004}, {"SMB3", 0xB7, 0x0004},
|
||||||
|
{"SMB4", 0xC7, 0x0004}, {"SMB5", 0xD7, 0x0004}, {"SMB6", 0xE7, 0x0004}, {"SMB7", 0xF7, 0x0004},
|
||||||
|
{"RMB", 0x07, 0x0004}, {"SMB", 0x87, 0x0004},
|
||||||
|
|
||||||
|
{"BBR0", 0x0F, 0x1004}, {"BBR1", 0x1F, 0x1004}, {"BBR2", 0x2F, 0x1004}, {"BBR3", 0x3F, 0x1004},
|
||||||
|
{"BBR4", 0x4F, 0x1004}, {"BBR5", 0x5F, 0x1004}, {"BBR6", 0x6F, 0x1004}, {"BBR7", 0x7F, 0x1004},
|
||||||
|
{"BBS0", 0x8F, 0x1004}, {"BBS1", 0x9F, 0x1004}, {"BBS2", 0xAF, 0x1004}, {"BBS3", 0xBF, 0x1004},
|
||||||
|
{"BBS4", 0xCF, 0x1004}, {"BBS5", 0xDF, 0x1004}, {"BBS6", 0xEF, 0x1004}, {"BBS7", 0xFF, 0x1004},
|
||||||
|
{"BBR", 0x0F, 0x1004}, {"BBS", 0x8F, 0x1004},
|
||||||
|
|
||||||
|
{"TRB", 0x10, 0x0024}, {"TSB", 0x00, 0x0024},
|
||||||
|
{"CPX", 0xE0, 0x0026}, {"CPY", 0xC0, 0x0026},
|
||||||
|
{"LDX", 0xA2, 0x00A6}, {"STX", 0x82, 0x00A6},
|
||||||
|
{"BIT", 0x20, 0x006E},
|
||||||
|
{"STZ", 0x60, 0x006C},
|
||||||
|
{"JMP", 0x4C, 0x0620},
|
||||||
|
{"JSR", 0x14, 0x0020},
|
||||||
|
{"LDY", 0xA0, 0x006E},
|
||||||
|
{"STY", 0x80, 0x002C},
|
||||||
|
{"", 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct opf {unsigned char token, opmod, opcode;};
|
||||||
|
|
||||||
|
struct opf opfix[] = {
|
||||||
|
{0x20, 0x08, 0x89},
|
||||||
|
{0xE0, 0x08, 0xE0},
|
||||||
|
{0xC0, 0x08, 0xC0},
|
||||||
|
{0xA0, 0x08, 0xA0},
|
||||||
|
{0xA2, 0x08, 0xA2},
|
||||||
|
{0xC2, 0x08, 0x3A},
|
||||||
|
{0xE2, 0x08, 0x1A},
|
||||||
|
{0x60, 0x0C, 0x9C},
|
||||||
|
{0x60, 0x1C, 0x9E},
|
||||||
|
{0xA2, 0x18, 0xBE},
|
||||||
|
{0x82, 0x18, 0xBC},
|
||||||
|
{0x4C, 0x0C, 0x4C},
|
||||||
|
{0x4C, 0x11, 0x6C},
|
||||||
|
{0x4C, 0x00, 0x7C},
|
||||||
|
{0,0,0}
|
||||||
|
};
|
||||||
|
|
10
c02.ppj
10
c02.ppj
|
@ -8,7 +8,7 @@ POC_PROJECT_TYPE = 13#
|
||||||
POC_PROJECT_OUTPUTDIR = output#
|
POC_PROJECT_OUTPUTDIR = output#
|
||||||
POC_PROJECT_RESULTDIR = .#
|
POC_PROJECT_RESULTDIR = .#
|
||||||
POC_PROJECT_ARGUMENTS = #
|
POC_PROJECT_ARGUMENTS = #
|
||||||
POC_PROJECT_WORKPATH = .#
|
POC_PROJECT_WORKPATH = src#
|
||||||
POC_PROJECT_EXECUTOR = #
|
POC_PROJECT_EXECUTOR = #
|
||||||
POC_PROJECT_ZIPEXTRA = #
|
POC_PROJECT_ZIPEXTRA = #
|
||||||
CC = pocc.exe#
|
CC = pocc.exe#
|
||||||
|
@ -153,8 +153,10 @@ output\label.obj: \
|
||||||
src\label.c \
|
src\label.c \
|
||||||
src\asm.h \
|
src\asm.h \
|
||||||
src\common.h \
|
src\common.h \
|
||||||
|
src\files.h \
|
||||||
src\label.h \
|
src\label.h \
|
||||||
src\parse.h
|
src\parse.h \
|
||||||
|
src\vars.h
|
||||||
$(CC) $(CCFLAGS) "$!" -Fo"$@"
|
$(CC) $(CCFLAGS) "$!" -Fo"$@"
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -164,9 +166,11 @@ output\parse.obj: \
|
||||||
src\parse.c \
|
src\parse.c \
|
||||||
src\asm.h \
|
src\asm.h \
|
||||||
src\common.h \
|
src\common.h \
|
||||||
|
src\expr.h \
|
||||||
src\files.h \
|
src\files.h \
|
||||||
src\label.h \
|
src\label.h \
|
||||||
src\parse.h
|
src\parse.h \
|
||||||
|
src\stmnt.h
|
||||||
$(CC) $(CCFLAGS) "$!" -Fo"$@"
|
$(CC) $(CCFLAGS) "$!" -Fo"$@"
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -35,3 +35,7 @@ void newlin(); //Advance cursor to beginning of next line
|
||||||
char putchr(); //Print ASCII character to Console
|
char putchr(); //Print ASCII character to Console
|
||||||
void setdst(); //Set Destination Pointer
|
void setdst(); //Set Destination Pointer
|
||||||
void setsrc(); //Set Source Pointer
|
void setsrc(); //Set Source Pointer
|
||||||
|
|
||||||
|
//System Labels
|
||||||
|
start: //Start of Code
|
||||||
|
exit: //Return to Operating System
|
||||||
|
|
|
@ -1,8 +1,26 @@
|
||||||
;Screen Control Assembly Lanuage Routines for Apple 1
|
;Screen Control Assembly Lanuage Routines for Apple 1
|
||||||
|
|
||||||
|
SUBROUTINE _SCREEN
|
||||||
|
|
||||||
|
SMTEXT EQU $00 ;Default Text Screen
|
||||||
|
SMWIDE EQU $FF ;Wide Text Screen (Undefined)
|
||||||
|
|
||||||
|
;Set Screen Mode
|
||||||
|
SETSCR: CMP SMTEXT ;If Default Text Screen
|
||||||
|
BEQ GETSCR ;Return Return 0
|
||||||
|
LDA #$FF ;Else Return ERROR
|
||||||
|
RTS
|
||||||
|
;Else Return 0
|
||||||
|
;Get Screen Mode
|
||||||
|
GETSCR: LDA #0 ;Return 0 (Default Text Mode)
|
||||||
|
RTS
|
||||||
|
|
||||||
;Clear the Screen
|
;Clear the Screen
|
||||||
CLRSCR: RTS ;Do Nothing (Drop to RTS)
|
CLRSCR: RTS ;Do Nothing (Drop to RTS)
|
||||||
|
|
||||||
|
;Move Cursor Home
|
||||||
|
CRSRHM EQU CLRSCR ;No Action
|
||||||
|
|
||||||
;Move Cursor to Specified Coordinates
|
;Move Cursor to Specified Coordinates
|
||||||
SETPOS EQU CLRSCR ;No Action
|
SETPOS EQU CLRSCR ;No Action
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
* screen - Screen Control Routines for C02 *
|
* screen - Screen Control Routines for C02 *
|
||||||
********************************************/
|
********************************************/
|
||||||
|
|
||||||
|
/* Screen Modes for getscr() and setscr() */
|
||||||
|
#define SMTEXT $00 //System Default Text Mode
|
||||||
|
#define SMWIDE $FF //Wide Screen Text Mode (Unsupported)
|
||||||
|
|
||||||
/* Clear the Screen */
|
/* Clear the Screen */
|
||||||
void clrscn();
|
void clrscn();
|
||||||
|
|
||||||
|
@ -13,6 +17,10 @@ void crsrhm();
|
||||||
* cursor row */
|
* cursor row */
|
||||||
char getpos();
|
char getpos();
|
||||||
|
|
||||||
|
/* Get Screen Mode *
|
||||||
|
* Returns: char mode - Current Screen Mode */
|
||||||
|
char getscr();
|
||||||
|
|
||||||
/* Get Screen Size *
|
/* Get Screen Size *
|
||||||
* Returns: width in columns *
|
* Returns: width in columns *
|
||||||
* height in rows */
|
* height in rows */
|
||||||
|
@ -22,3 +30,9 @@ char getsiz();
|
||||||
* Args: column - screen column (0 = left) *
|
* Args: column - screen column (0 = left) *
|
||||||
* row - screen line (0 = top) */
|
* row - screen line (0 = top) */
|
||||||
void setpos();
|
void setpos();
|
||||||
|
|
||||||
|
/* Set Screen Mode *
|
||||||
|
* Args: char mode - screen mode *
|
||||||
|
* 0 = default text mode *
|
||||||
|
* Returns: $FF if Mode Invalid */
|
||||||
|
char setscr();
|
||||||
|
|
|
@ -1,5 +1,20 @@
|
||||||
;Screen Control Assembly Lanuage Routines for Apple II
|
;Screen Control Assembly Lanuage Routines for Apple II
|
||||||
|
|
||||||
|
SUBROUTINE _SCREEN
|
||||||
|
|
||||||
|
SMTEXT EQU $00 ;Default Text Screen
|
||||||
|
SMWIDE EQU $FF ;Wide Text Screen (Undefined)
|
||||||
|
|
||||||
|
;Set Screen Mode
|
||||||
|
SETSCR: CMP SMTEXT ;If Default Text Screen
|
||||||
|
BEQ GETSCR ;Return Return 0
|
||||||
|
LDA #$FF ;Else Return ERROR
|
||||||
|
RTS
|
||||||
|
;Else Return 0
|
||||||
|
;Get Screen Mode
|
||||||
|
GETSCR: LDA #0 ;Return 0 (Default Text Mode)
|
||||||
|
RTS
|
||||||
|
|
||||||
;Clear the Screen
|
;Clear the Screen
|
||||||
CLRSCR: EQU $FC58 ;Applesoft Routine HOME
|
CLRSCR: EQU $FC58 ;Applesoft Routine HOME
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
/********************************************
|
/*****************************************
|
||||||
* screen - Screen Control Routines for C02 *
|
* Screen Control Functions for Apple II *
|
||||||
********************************************/
|
****************************************/
|
||||||
|
|
||||||
|
/* Screen Modes for getscr() and setscr() */
|
||||||
|
#define SMTEXT $00 //System Default Text Mode
|
||||||
|
#define SMWIDE $FF //Wide Screen Text Mode (Unsupported)
|
||||||
|
|
||||||
/* Clear the Screen */
|
/* Clear the Screen */
|
||||||
void clrscn();
|
void clrscn();
|
||||||
|
@ -18,7 +22,17 @@ char getpos();
|
||||||
* height in rows */
|
* height in rows */
|
||||||
char getsiz();
|
char getsiz();
|
||||||
|
|
||||||
|
/* Get Screen Mode *
|
||||||
|
* Returns: char mode - Current Screen Mode */
|
||||||
|
char getscr();
|
||||||
|
|
||||||
/* Move Cursor to Specified Position *
|
/* Move Cursor to Specified Position *
|
||||||
* Args: column - screen column (0 = left) *
|
* Args: column - screen column (0 = left) *
|
||||||
* row - screen line (0 = top) */
|
* row - screen line (0 = top) */
|
||||||
void setpos();
|
void setpos();
|
||||||
|
|
||||||
|
/* Set Screen Mode *
|
||||||
|
* Args: char mode - screen mode *
|
||||||
|
* 0 = default text mode *
|
||||||
|
* Returns: $FF if Mode Invalid */
|
||||||
|
char setscr();
|
||||||
|
|
|
@ -1,26 +1,29 @@
|
||||||
; c02 Program Initialization Code for Unexpanded VIC-20
|
; c02 Program Initialization Code for Commodore 64
|
||||||
|
|
||||||
;PETSCII Key Mappings
|
;PETSCII Key Mappings
|
||||||
DELKEY EQU $14 ;Delete/Backspace Key (Delete)
|
DELKEY EQU $14 ;Delete/Backspace Key (Delete)
|
||||||
ESCKEY EQU $03 ;Escape/Stop Key (RUN/STOP)
|
ESCKEY EQU $03 ;Escape/Stop Key (RUN/STOP)
|
||||||
RTNKEY EQU $0D ;Return/Enter Key (RETURN)
|
RTNKEY EQU $0D ;Return/Enter Key (RETURN)
|
||||||
|
|
||||||
;Zero Page Variables
|
;Zero Page Variables
|
||||||
SRCLO EQU $22 ;Source Pointer LSB [Temporary Pointers]
|
XMBANK EQU $0A ;Extended Memory Bank (Load/Verify Flag)
|
||||||
SRCHI EQU $23 ;Source Pointer MSB [Temporary Pointers]
|
XADRLO EQU $0B ;Ext Memory Address LSB (Text Index/Array Size)
|
||||||
DSTLO EQU $24 ;Destination Pointer LSB [Temporary Pointers]
|
XADRHI EQU $0C ;Ext Memory Address MSB (Array Dimension Fkags)
|
||||||
DSTHI EQU $25 ;Destination Pointer MSB [Temporary Pointers]
|
SRCLO EQU $22 ;Source Pointer LSB [Temporary Pointers]
|
||||||
BLKLO EQU $26 ;Block Pointer LSB [Floating Point Work Area]
|
SRCHI EQU $23 ;Source Pointer MSB [Temporary Pointers]
|
||||||
BLKHI EQU $27 ;Block Pointer MSB [Floating Point Work Area]
|
DSTLO EQU $24 ;Destination Pointer LSB [Temporary Pointers]
|
||||||
STKLO EQU $28 ;Stack Pointer LSB [Floating Point Work Area]
|
DSTHI EQU $25 ;Destination Pointer MSB [Temporary Pointers]
|
||||||
STKHI EQU $29 ;Stack Pointer MSB [Floating Point Work Area]
|
BLKLO EQU $26 ;Block Pointer LSB [Floating Point Work Area]
|
||||||
BFRLO EQU $35 ;Buffer Pointer LSB [Temporary String Pointer]
|
BLKHI EQU $27 ;Block Pointer MSB [Floating Point Work Area]
|
||||||
BFRHI EQU $36 ;Buffer Pointer MSB [Temporary String Pointer]
|
STKLO EQU $28 ;Stack Pointer LSB [Floating Point Work Area]
|
||||||
RDSEED EQU $A2 ;Random Seed [Software Jiffy Clock (Low Byte)]
|
STKHI EQU $29 ;Stack Pointer MSB [Floating Point Work Area]
|
||||||
TEMP0 EQU $FB ;Temporary Variable [Unused Byte]
|
BFRLO EQU $35 ;Buffer Pointer LSB [Temporary String Pointer]
|
||||||
TEMP1 EQU $FC ;Temporary Variable [Unused Byte]
|
BFRHI EQU $36 ;Buffer Pointer MSB [Temporary String Pointer]
|
||||||
TEMP2 EQU $FD ;Temporary Variable [Unused Byte]
|
RDSEED EQU $A2 ;Random Seed [Software Jiffy Clock (Low Byte)]
|
||||||
TEMP3 EQU $FE ;Temporary Variable [Unused Byte]
|
TEMP0 EQU $FB ;Temporary Variable [Unused Byte]
|
||||||
|
TEMP1 EQU $FC ;Temporary Variable [Unused Byte]
|
||||||
|
TEMP2 EQU $FD ;Temporary Variable [Unused Byte]
|
||||||
|
TEMP3 EQU $FE ;Temporary Variable [Unused Byte]
|
||||||
|
|
||||||
;System Variables
|
;System Variables
|
||||||
USER3 EQU $0313 ;Free Byte for User Programs
|
USER3 EQU $0313 ;Free Byte for User Programs
|
||||||
|
@ -51,7 +54,7 @@ FSFLFA EQU $F314 ;Find Logical File A
|
||||||
|
|
||||||
;Machine Language Basic Stub
|
;Machine Language Basic Stub
|
||||||
ORG $0801 ;Start of Basic Program
|
ORG $0801 ;Start of Basic Program
|
||||||
BASIC: DC $0C, $10 ;Pointer to Next Line (4109)
|
BASIC: DC $0C, $08 ;Pointer to Next Line
|
||||||
DC $00, $00 ;Line Number (0)
|
DC $00, $00 ;Line Number (0)
|
||||||
DC $9E ;SYS
|
DC $9E ;SYS
|
||||||
DC $20 ;' '
|
DC $20 ;' '
|
||||||
|
@ -91,4 +94,8 @@ NEWLIN: LDX #0 ;Store 0
|
||||||
STX $D3 ;in Cursor Column and
|
STX $D3 ;in Cursor Column and
|
||||||
JMP $E87C ;Execute NXTLINE Routine
|
JMP $E87C ;Execute NXTLINE Routine
|
||||||
|
|
||||||
|
;Print Zero Delimited String to Screen
|
||||||
|
PUTSTR: TXA ;Copy LSB to Accumulator
|
||||||
|
JMP $AB1E ;Execute STROUT
|
||||||
|
|
||||||
INCLUDE "../include/prbyte.a02" ;PRBYTE and PRHEX routine
|
INCLUDE "../include/prbyte.a02" ;PRBYTE and PRHEX routine
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;Joystick Assembly Language Module for C64
|
;Joystick Assembly Language Module for C64
|
||||||
|
|
||||||
JYSTKS EQU $04 ;Number of Joysticks
|
JYSTKS EQU $02 ;Number of Joysticks
|
||||||
|
|
||||||
;Joystick Bit Masks
|
;Joystick Bit Masks
|
||||||
JOYUP EQU $01 ;Bit 0 - Up
|
JOYUP EQU $01 ;Bit 0 - Up
|
||||||
|
@ -12,14 +12,11 @@ JOYB0 EQU $10 ;Bit 4 - Button
|
||||||
;Read Joystick
|
;Read Joystick
|
||||||
JOYSTK: CMP #JYSTKS ;If Invalid Joystick#
|
JOYSTK: CMP #JYSTKS ;If Invalid Joystick#
|
||||||
BCS JOYSTZ ; Return Error
|
BCS JOYSTZ ; Return Error
|
||||||
|
EOR #1 ;Invert Joystick #
|
||||||
TAX ;Copy Joystick # to X
|
TAX ;Copy Joystick # to X
|
||||||
LDA $0284,X ;Read Trigger Control Register
|
|
||||||
ROR ;Move Bit 0 into Carry
|
|
||||||
LDA $DC00,X ;Read Joystick Shadow Register
|
LDA $DC00,X ;Read Joystick Shadow Register
|
||||||
EOR #$FF ;Invert and
|
EOR #$FF ;Invert and
|
||||||
AND #$0F ;Mask Bits
|
AND #$1F ;Mask Bits
|
||||||
BCS JOYSTX ;If Trigger Pressed
|
JOYSTX: RTS
|
||||||
ORA #$10 ; Set Bit 4
|
|
||||||
HOYSTX: RTS
|
|
||||||
JOYSTZ: LDA #$FF ;Return Error
|
JOYSTZ: LDA #$FF ;Return Error
|
||||||
RTS
|
RTS
|
||||||
|
|
37
include/c64/keydef.a02
Normal file
37
include/c64/keydef.a02
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
;PETSCII Key Code Definitions
|
||||||
|
;for Commmodore 64 Computer
|
||||||
|
|
||||||
|
KEYBCK EQU $00 ;Backspace [N/A]
|
||||||
|
KEYBRK EQU $03 ;Break (RUN/STOP)
|
||||||
|
KEYCLR EQU $93 ;Clear (Shift-CLR/HOME)
|
||||||
|
KEYCPY EQU $00 ;Copy [N/A]
|
||||||
|
KEYDEL EQU $14 ;Delete
|
||||||
|
KEYDN EQU $11 ;Cursor Down
|
||||||
|
KEYESC EQU $00 ;Escape [N/A]
|
||||||
|
KEYFN1 EQU $85 ;F1 (F1/F2)
|
||||||
|
KEYFN2 EQU $89 ;F2 (Shift-F1/F2)
|
||||||
|
KEYFN3 EQU $86 ;F3 (F3/F4)
|
||||||
|
KEYFN4 EQU $8A ;F4 (Shift-F3/F4)
|
||||||
|
KEYFN5 EQU $87 ;F5 (F5/F6)
|
||||||
|
KEYFN6 EQU $8B ;F6 (Shift-F5/F6)
|
||||||
|
KEYFN7 EQU $88 ;F7 (F7/F8)
|
||||||
|
KEYFN8 EQU $8C ;F8 (Shift-F7/F8)
|
||||||
|
KEYFN9 EQU $00 ;F9 [N/A]
|
||||||
|
KEYFNA EQU $00 ;F10 [N/A]
|
||||||
|
KEYFNB EQU $00 ;F11 [N/A]
|
||||||
|
KEYFNC EQU $00 ;F12 [N/A]
|
||||||
|
KEYHLP EQU $84 ;Help [N/A]
|
||||||
|
KEYHOM EQU $13 ;Home (CLR/HOME)
|
||||||
|
KEYINS EQU $94 ;Insert (Shift-INS/DEL)
|
||||||
|
KEYLFT EQU $9D ;Cursor Left
|
||||||
|
KEYLNF EQU $00 ;Line Feed [N/A]
|
||||||
|
KEYRGT EQU $1D ;Cursor Right
|
||||||
|
KEYRTN EQU $0D ;Return
|
||||||
|
KEYRTS EQU $8D ;Shift-Return
|
||||||
|
KEYRUN EQU $00 ;Run (Shift-RUN/STOP)
|
||||||
|
KEYRVF EQU $92 ;Reverse Off
|
||||||
|
KEYRVS EQU $12 ;Reverse On
|
||||||
|
KEYSPS EQU $A0 ;Shifted Space
|
||||||
|
KEYTAB EQU $09 ;Tab
|
||||||
|
KEYTAS EQU $00 ;Shift-Tab [N/A]
|
||||||
|
KEYUP EQU $91 ;Cursor Up
|
37
include/c64/keydef.h02
Normal file
37
include/c64/keydef.h02
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/* PETSCII Key Code Definitions *
|
||||||
|
* for Commodore 64 Computer */
|
||||||
|
|
||||||
|
#define KEYBCK $00 //Backspace
|
||||||
|
#define KEYBRK $03 //Break (RUN/STOP)
|
||||||
|
#define KEYCLR $93 //Clear (Shift-CLR/HOME)
|
||||||
|
#define KEYCPY $00 //Copy [N/A]
|
||||||
|
#define KEYDEL $14 //Delete
|
||||||
|
#define KEYDN $11 //Cursor Down
|
||||||
|
#define KEYESC $00 //Escape [N/A]
|
||||||
|
#define KEYFN1 $85 //Function Key 1 (F1/F2)
|
||||||
|
#define KEYFN2 $89 //Function Key 2 (Shift-F1/F2)
|
||||||
|
#define KEYFN3 $86 //Function Key 3 (F3/F4)
|
||||||
|
#define KEYFN4 $8A //Function Key 4 (Shift-F3/F4)
|
||||||
|
#define KEYFN5 $87 //Function Key 5 (F5/F6)
|
||||||
|
#define KEYFN6 $8B //Function Key 6 (Shift-F5/F6)
|
||||||
|
#define KEYFN7 $88 //Function Key 7 (F7/F8)
|
||||||
|
#define KEYFN8 $8C //Function Key 8 (Shift-F7/F8) [HELP on C16]
|
||||||
|
#define KEYFN9 $00 //Function Key 9 [N/A]
|
||||||
|
#define KEYFNA $00 //Function Key 10 [N/A]
|
||||||
|
#define KEYFNB $00 //Function Key 11 [N/A]
|
||||||
|
#define KEYFNC $00 //Function Key 12 [N/A]
|
||||||
|
#define KEYHLP $84 //Help [N/A]
|
||||||
|
#define KEYHOM $13 //Home (CLR/HOME)
|
||||||
|
#define KEYINS $94 //Insert (Shift-INS/DEL)
|
||||||
|
#define KEYLFT $9D //Cursor Left
|
||||||
|
#define KEYLNF $00 //Line Feed (N/A)
|
||||||
|
#define KEYRGT $1D //Cursor Right
|
||||||
|
#define KEYRTN $0D //Return
|
||||||
|
#define KEYRTS $8D //Shift-Return
|
||||||
|
#define KEYRUN $00 //Run (Shift-RUN/STOP)
|
||||||
|
#define KEYRVF $92 //Reverse Off
|
||||||
|
#define KEYRVS $12 //Reverse On
|
||||||
|
#define KEYSPS $A0 //Shifted Space
|
||||||
|
#define KEYTAB $09 //Tab
|
||||||
|
#define KEYTAS $00 //Shift-Tab [N/A]
|
||||||
|
#define KEYUP $91 //Cursor Up
|
|
@ -1,5 +1,20 @@
|
||||||
;Screen Control Assembly Lanuage Routines for VIC-20
|
;Screen Control Assembly Lanuage Routines for VIC-20
|
||||||
|
|
||||||
|
SUBROUTINE _SCREEN
|
||||||
|
|
||||||
|
SMTEXT EQU $00 ;Default Text Screen
|
||||||
|
SMWIDE EQU $FF ;Wide Text Screen (Undefined)
|
||||||
|
|
||||||
|
;Set Screen Mode
|
||||||
|
SETSCR: CMP SMTEXT ;If Default Text Screen
|
||||||
|
BEQ GETSCR ;Return Return 0
|
||||||
|
LDA #$FF ;Else Return ERROR
|
||||||
|
RTS
|
||||||
|
;Else Return 0
|
||||||
|
;Get Screen Mode
|
||||||
|
GETSCR: LDA #0 ;Return 0 (Default Text Mode)
|
||||||
|
RTS
|
||||||
|
|
||||||
;Clear the Screen
|
;Clear the Screen
|
||||||
CLRSCR EQU $E544 ;Aliased to CLSR Routine
|
CLRSCR EQU $E544 ;Aliased to CLSR Routine
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
* Screen Control Functions and Constants for VIC-20 *
|
* Screen Control Functions and Constants for VIC-20 *
|
||||||
*****************************************************/
|
*****************************************************/
|
||||||
|
|
||||||
|
/* Screen Modes for getscr() and setscr() */
|
||||||
|
#define SMTEXT $00 //System Default Text Mode
|
||||||
|
#define SMWIDE $FF //Wide Screen Text Mode (Unsupported)
|
||||||
|
|
||||||
/* Clear the Screen */
|
/* Clear the Screen */
|
||||||
void clrscn();
|
void clrscn();
|
||||||
|
|
||||||
|
@ -18,7 +22,17 @@ char getpos();
|
||||||
* height in rows */
|
* height in rows */
|
||||||
char getsiz();
|
char getsiz();
|
||||||
|
|
||||||
|
/* Get Screen Mode *
|
||||||
|
* Returns: char mode - Current Screen Mode */
|
||||||
|
char getscr();
|
||||||
|
|
||||||
/* Move Cursor to Specified Position *
|
/* Move Cursor to Specified Position *
|
||||||
* Args: column - screen column (0 = left) *
|
* Args: column - screen column (0 = left) *
|
||||||
* row - screen line (0 = top) */
|
* row - screen line (0 = top) */
|
||||||
void setpos();
|
void setpos();
|
||||||
|
|
||||||
|
/* Set Screen Mode *
|
||||||
|
* Args: char mode - screen mode *
|
||||||
|
* 0 = default text mode *
|
||||||
|
* Returns: $FF if Mode Invalid */
|
||||||
|
char setscr();
|
||||||
|
|
37
include/cbm/keydef.a02
Normal file
37
include/cbm/keydef.a02
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
;PETSCII Key Code Definitions
|
||||||
|
;Common to All PET/CBM Computers
|
||||||
|
|
||||||
|
KEYBCK EQU $00 ;Backspace [N/A]
|
||||||
|
KEYBRK EQU $03 ;Break (RUN/STOP)
|
||||||
|
KEYCLR EQU $93 ;Clear (Shift-CLR/HOME)
|
||||||
|
KEYCPY EQU $00 ;Copy [N/A]
|
||||||
|
KEYDEL EQU $14 ;Delete
|
||||||
|
KEYDN EQU $11 ;Cursor Down
|
||||||
|
KEYESC EQU $00 ;Escape [C128/C65]
|
||||||
|
KEYFN1 EQU $85 ;F1 [VIC20/C64/C16/C128/C65]
|
||||||
|
KEYFN2 EQU $89 ;F2 [VIC20/C64/C16/C128/C65]
|
||||||
|
KEYFN3 EQU $86 ;F3 [VIC20/C64/C16/C128/C65]
|
||||||
|
KEYFN4 EQU $8A ;F4 [VIC20/C64/C16/C128/C65]
|
||||||
|
KEYFN5 EQU $87 ;F5 [VIC20/C64/C16/C128/C65]
|
||||||
|
KEYFN6 EQU $8B ;F6 [VIC20/C64/C16/C128/C65]
|
||||||
|
KEYFN7 EQU $88 ;F7 [VIC20/C64/C16/C128/C65]
|
||||||
|
KEYFN8 EQU $8C ;F8 [VIC20/C64/C128/C65] [HELP on C16]
|
||||||
|
KEYFN9 EQU $00 ;F9 [C65]
|
||||||
|
KEYFNA EQU $00 ;F10 [C65]
|
||||||
|
KEYFNB EQU $00 ;F11 [C65]
|
||||||
|
KEYFNC EQU $00 ;F12 [C65]
|
||||||
|
KEYHLP EQU $84 ;Help [C128/xC65]
|
||||||
|
KEYHOM EQU $13 ;Home (CLR/HOME)
|
||||||
|
KEYINS EQU $94 ;Insert (Shift-INS/DEL)
|
||||||
|
KEYLFT EQU $9D ;Cursor Left
|
||||||
|
KEYLNF EQU $00 ;Line Feed [C128]
|
||||||
|
KEYRGT EQU $1D ;Cursor Right
|
||||||
|
KEYRTN EQU $0D ;Return
|
||||||
|
KEYRTS EQU $8D ;Shift-Return
|
||||||
|
KEYRUN EQU $00 ;Run (Shift-RUN/STOP)
|
||||||
|
KEYRVF EQU $92 ;Reverse Off
|
||||||
|
KEYRVS EQU $12 ;Reverse On
|
||||||
|
KEYSPS EQU $A0 ;Shifted Space
|
||||||
|
KEYTAB EQU $09 ;Tab
|
||||||
|
KEYTAS EQU $00 ;Shift-Tab [C128/C65]
|
||||||
|
KEYUP EQU $91 ;Cursor Up
|
37
include/cbm/keydef.h02
Normal file
37
include/cbm/keydef.h02
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/* PETSCII Key Code Definitions *
|
||||||
|
* Common to All PET/CBM Computers */
|
||||||
|
|
||||||
|
#define KEYBCK $00 //Backspace
|
||||||
|
#define KEYBRK $03 //Break (RUN/STOP)
|
||||||
|
#define KEYCLR $93 //Clear (Shift-CLR/HOME)
|
||||||
|
#define KEYCPY $00 //Copy
|
||||||
|
#define KEYDEL $20 //Delete
|
||||||
|
#define KEYDN $11 //Cursor Down
|
||||||
|
#define KEYESC $00 //Escape (N/A)
|
||||||
|
#define KEYFN1 $00 //F1 (N/A)
|
||||||
|
#define KEYFN2 $00 //F2 (N/A)
|
||||||
|
#define KEYFN3 $00 //F3 (N/A)
|
||||||
|
#define KEYFN4 $00 //F4 (N/A)
|
||||||
|
#define KEYFN5 $00 //F5 (N/A)
|
||||||
|
#define KEYFN6 $00 //F6 (N/A)
|
||||||
|
#define KEYFN7 $00 //F7 (N/A)
|
||||||
|
#define KEYFN8 $00 //F8 (N/A)
|
||||||
|
#define KEYFN9 $00 //F9 (N/A)
|
||||||
|
#define KEYFNA $00 //F10 (N/A)
|
||||||
|
#define KEYFNB $00 //F11 (N/A)
|
||||||
|
#define KEYFNC $00 //F12 (N/A)
|
||||||
|
#define KEYHLP $00 //Help (N/A)
|
||||||
|
#define KEYHOM $13 //Home (CLR/HOME)
|
||||||
|
#define KEYINS $94 //Insert (Shift-INS/DEL)
|
||||||
|
#define KEYLFT $9C //Cursor Left
|
||||||
|
#define KEYLNF $00 //Line Feed (N/A)
|
||||||
|
#define KEYRGT $1D //Cursor Right
|
||||||
|
#define KEYRTN $0D //Return
|
||||||
|
#define KEYRTS $8D //Shift-Return
|
||||||
|
#define KEYRUN $83 //Run (Shift-RUN/STOP)
|
||||||
|
#define KEYRVF $92 //Reverse Off
|
||||||
|
#define KEYRVS $12 //Reverse On
|
||||||
|
#define KEYSPS $A0 //Shifted Space
|
||||||
|
#define KEYTAB $09 //Tab
|
||||||
|
#define KEYTAS $00 //Shift-Tab (N/A)
|
||||||
|
#define KEYUP $91 //Cursor Up
|
|
@ -37,6 +37,10 @@ STKEHI EQU $2B
|
||||||
STKLO EQU $2C ;Stack Pointer
|
STKLO EQU $2C ;Stack Pointer
|
||||||
STKHI EQU $2D
|
STKHI EQU $2D
|
||||||
|
|
||||||
|
;Placeholders Labels for the Example Code Below
|
||||||
|
POLKEY EQU $FFFE ;ROM Read Key Routine
|
||||||
|
WSTART EQU $FFFF ;BASIC Warm Start Routine
|
||||||
|
|
||||||
ORG $0200 ;Program Start Address
|
ORG $0200 ;Program Start Address
|
||||||
|
|
||||||
START: NOP ;System specific initialization code
|
START: NOP ;System specific initialization code
|
||||||
|
@ -77,45 +81,5 @@ NEWLIN: RTS ;Code to move Cursor to beginning of next line
|
||||||
;Print Character to Screen
|
;Print Character to Screen
|
||||||
PUTCHR RTS ;Code to write ASCII character to Screen
|
PUTCHR RTS ;Code to write ASCII character to Screen
|
||||||
|
|
||||||
;Clear the Screen
|
INCLUDE "../include/prbyte.a02" ;PRBYTE and PRHEX routines
|
||||||
CLRSCR: RTS ;Code to Clear Screen
|
|
||||||
|
|
||||||
;Move Cursor to Specified Coordinates
|
|
||||||
SETPOS: RTS ;Move Cursor to Column A, Row Y
|
|
||||||
|
|
||||||
;Get Cursor Position
|
|
||||||
GETPOS: RTS ;Return Cursor Column in A, Row in Y
|
|
||||||
|
|
||||||
;Get Screen Size
|
|
||||||
GETSIZ: RTS ;Return Screen Width in A, Height in Y
|
|
||||||
|
|
||||||
;Note: The following two functions replicate calls available
|
|
||||||
;in the Apple-1 monitor and are included for test purposes
|
|
||||||
;They will likely be removed before the final release
|
|
||||||
|
|
||||||
;Print Byte as Two-Digit Hex Number to Console
|
|
||||||
PRBYTE: PHA ;Save Accumulater
|
|
||||||
LSR ;Shift Hi Nybble to Low Nybble
|
|
||||||
LSR
|
|
||||||
LSR
|
|
||||||
LSR
|
|
||||||
JSR PRHEX ; and Print it
|
|
||||||
PLA ;Restore Accumulator
|
|
||||||
; and fall into PRHEX
|
|
||||||
|
|
||||||
;Print Low Nybble as Hex Digit to Console
|
|
||||||
PRHEX: AND #$0F ;Strip High Nybb
|
|
||||||
SED ;Set Decimal Flag for
|
|
||||||
CLC ; Addition Wizardry
|
|
||||||
ADC #$90 ;Convert to $90-$99,$00-$05
|
|
||||||
ADC #$40 ;Convert to $30-$39,$41-$46
|
|
||||||
CLD ;Clear Decimal Flag
|
|
||||||
JMP PUTCHR ;Print Hex Digit and Return
|
|
||||||
|
|
||||||
;Alternate Code for Systems with Interrupts that don't CLD
|
|
||||||
PRHEX: AND #$0F ;Strip High Nybble
|
|
||||||
CMP #$0A ;If Low Nybble >= 10
|
|
||||||
BCC PRHEXC ;
|
|
||||||
ADC #$06 ; Convert ':' to 'A'...
|
|
||||||
PRHEXC: ADC #$30 ;Convert to ASCII Character
|
|
||||||
JMP PUTCHR ;Print Hex Digit and Return
|
|
|
@ -36,15 +36,12 @@ char rdseed; //System Seed for Pseudo-Random Number Generator
|
||||||
//System Subroutines
|
//System Subroutines
|
||||||
void delchr(); //Delete previous character
|
void delchr(); //Delete previous character
|
||||||
char getkey(); //Read ASCII character from Console
|
char getkey(); //Read ASCII character from Console
|
||||||
char getpos(); //Get Cursor Position
|
|
||||||
char getsiz(); //Get Screen Size
|
|
||||||
void newlin(); //Advance cursor to beginning of next line
|
void newlin(); //Advance cursor to beginning of next line
|
||||||
char polkey(); //Poll Console for character
|
char polkey(); //Poll Console for character
|
||||||
char putchr(); //Print ASCII character to Console
|
char putchr(); //Print ASCII character to Console
|
||||||
void prbyte(); //Print Accumulator as Hexadadecimal number
|
void prbyte(); //Print Accumulator as Hexadadecimal number
|
||||||
void prhex(); //Print Low Nybble of Accumulator as Hex Digit
|
void prhex(); //Print Low Nybble of Accumulator as Hex Digit
|
||||||
char getchr(); //Wait for character from Console
|
char getchr(); //Wait for character from Console
|
||||||
void setpos(); //Set Cursor Position
|
|
||||||
|
|
||||||
//System Labels
|
//System Labels
|
||||||
start: //Start of Code
|
start: //Start of Code
|
||||||
|
|
37
include/keydef.a02
Normal file
37
include/keydef.a02
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
;Standard ASCII Key Code Definitions
|
||||||
|
;Undefined Keys hae value $00
|
||||||
|
|
||||||
|
KEYBCK EQU $08 ;Backspace
|
||||||
|
KEYBRK EQU $03 ;Break
|
||||||
|
KEYCLR EQU $00 ;Clear
|
||||||
|
KEYCPY EQU $00 ;Copy [Acorn Atom]
|
||||||
|
KEYDEL EQU $7F ;Delete
|
||||||
|
KEYDN EQU $00 ;Cursor Down
|
||||||
|
KEYESC EQU $1B ;Escape
|
||||||
|
KEYFN1 EQU $00 ;F1
|
||||||
|
KEYFN2 EQU $00 ;F2
|
||||||
|
KEYFN3 EQU $00 ;F3
|
||||||
|
KEYFN4 EQU $00 ;F4
|
||||||
|
KEYFN5 EQU $00 ;F5
|
||||||
|
KEYFN6 EQU $00 ;F6
|
||||||
|
KEYFN7 EQU $00 ;F7
|
||||||
|
KEYFN8 EQU $00 ;F8
|
||||||
|
KEYFN9 EQU $00 ;F9
|
||||||
|
KEYFNA EQU $00 ;F10
|
||||||
|
KEYFNB EQU $00 ;F11
|
||||||
|
KEYFNC EQU $00 ;F12
|
||||||
|
KEYHLP EQU $00 ;Help [C128/C65]
|
||||||
|
KEYHOM EQU $00 ;Home
|
||||||
|
KEYINS EQU $00 ;Insert
|
||||||
|
KEYLFT EQU $00 ;Cursor Left
|
||||||
|
KEYLNF EQU $0A ;;Line Feed [C128]
|
||||||
|
KEYRGT EQU $00 ;Cursor Right
|
||||||
|
KEYRTN EQU $0D ;Return
|
||||||
|
KEYRTS EQU $80 ;Shift-Return
|
||||||
|
KEYRUN EQU $00 ;Run [PET/CBM]
|
||||||
|
KEYRVF EQU $92 ;Reverse OffCtrl-0
|
||||||
|
KEYRVS EQU $12 ;Reverse On Ctrl-9
|
||||||
|
KEYSPS EQU $00 ;Shifted Space
|
||||||
|
KEYTAB EQU $09 ;Tab
|
||||||
|
KEYTAS EQU $00 ;Shift-Tab
|
||||||
|
KEYUP EQU $00 ;Cursor Up
|
37
include/keydef.h02
Normal file
37
include/keydef.h02
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/* Standard ASCII Key Code Definitions *
|
||||||
|
* Undefined Keys hae value $00 *
|
||||||
|
|
||||||
|
#define KEYBCK $08 //Backspace
|
||||||
|
#define KEYBRK $03 //Break
|
||||||
|
#define KEYCLR $00 //Clear
|
||||||
|
#define KEYCPY $00 //Copy
|
||||||
|
#define KEYDEL $7F //Delete
|
||||||
|
#define KEYDN $00 //Cursor Down
|
||||||
|
#define KEYESC $1B //Escape
|
||||||
|
#define KEYFN1 $00 //1
|
||||||
|
#define KEYFN2 $00 //2
|
||||||
|
#define KEYFN3 $00 //3
|
||||||
|
#define KEYFN4 $00 //4
|
||||||
|
#define KEYFN5 $00 //5
|
||||||
|
#define KEYFN6 $00 //6
|
||||||
|
#define KEYFN7 $00 //7
|
||||||
|
#define KEYFN8 $00 //8
|
||||||
|
#define KEYFN9 $00 //9
|
||||||
|
#define KEYFNA $00 //10
|
||||||
|
#define KEYFNB $00 //11
|
||||||
|
#define KEYFNC $00 //12
|
||||||
|
#define KEYHLP $00 //Help
|
||||||
|
#define KEYHOM $00 //Home
|
||||||
|
#define KEYINS $00 //Insert
|
||||||
|
#define KEYLFT $00 //Cursor Left
|
||||||
|
#define KEYLNF $0A //Line Feed
|
||||||
|
#define KEYRGT $00 //Cursor Right
|
||||||
|
#define KEYRTN $0D //Return
|
||||||
|
#define KEYRTS $80 //Shift-Return
|
||||||
|
#define KEYRUN $00 //Run
|
||||||
|
#define KEYRVF $92 //Reverse Off
|
||||||
|
#define KEYRVS $12 //Reverse On
|
||||||
|
#define KEYSPS $00 //Shifted Space
|
||||||
|
#define KEYTAB $09 //Tab
|
||||||
|
#define KEYTAS $00 //Shift-Tab
|
||||||
|
#define KEYUP $00 //Cursor Up
|
39
include/orao/screen.a02
Normal file
39
include/orao/screen.a02
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
;Screen Control Assembly Lanuage Routines for C02
|
||||||
|
;Skeleton Code for Systems with no Screen Control
|
||||||
|
|
||||||
|
SUBROUTINE _SCREEN
|
||||||
|
|
||||||
|
SMTEXT EQU $00 ;Default Text Screen
|
||||||
|
SMWIDE EQU $FF ;Wide Text Screen (Undefined)
|
||||||
|
|
||||||
|
;Set Screen Mode
|
||||||
|
SETSCR: CMP SMTEXT ;If Default Text Screen
|
||||||
|
BEQ GETSCR ;Return Return 0
|
||||||
|
LDA #$FF ;Else Return ERROR
|
||||||
|
RTS
|
||||||
|
;Else Return 0
|
||||||
|
;Get Screen Mode
|
||||||
|
GETSCR: LDA #0 ;Return 0 (Default Text Mode)
|
||||||
|
RTS
|
||||||
|
|
||||||
|
;Clear the Screen
|
||||||
|
CLRSCR: LDA #$0C ;Print Form Feed
|
||||||
|
JMP PUTCHR ;and Return
|
||||||
|
|
||||||
|
;Move Cursor Home
|
||||||
|
CRSRHM EQU $E395 ;Aliad to HOME Routine
|
||||||
|
|
||||||
|
;Move Cursor to Specified Coordinates
|
||||||
|
SETPOS: STA $E9 ;Set CURCOL
|
||||||
|
STY $E8 ;Set CURROW
|
||||||
|
JMP $E39D ;Set Pointers and Return
|
||||||
|
|
||||||
|
;Get Cursor Position
|
||||||
|
GETPOS: LDA $E9 ;Load Column Position
|
||||||
|
LDY $E8 ;Load Row Position
|
||||||
|
RTS ;Return Cursor Column in A, Row in Y
|
||||||
|
|
||||||
|
;Get Screen Size
|
||||||
|
GETSIZ: LDA #32 ;Return 32 Columns
|
||||||
|
TAY ;and 32 Rows
|
||||||
|
RTS
|
38
include/orao/screen.h02
Normal file
38
include/orao/screen.h02
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*********************************************
|
||||||
|
* Screen Control Routines for Orao Computer *
|
||||||
|
*********************************************/
|
||||||
|
|
||||||
|
/* Screen Modes for getscr() and setscr() */
|
||||||
|
#define SMTEXT $00 //System Default Text Mode
|
||||||
|
#define SMWIDE $FF //Wide Screen Text Mode (Unsupported)
|
||||||
|
|
||||||
|
/* Clear the Screen */
|
||||||
|
void clrscn();
|
||||||
|
|
||||||
|
/* Move Cursor to Top Left of Screen */
|
||||||
|
void crsrhm();
|
||||||
|
|
||||||
|
/* Get Current Cursor Position *
|
||||||
|
* Returns: cursor column *
|
||||||
|
* cursor row */
|
||||||
|
char getpos();
|
||||||
|
|
||||||
|
/* Get Screen Mode *
|
||||||
|
* Returns: char mode - Current Screen Mode */
|
||||||
|
char getscr();
|
||||||
|
|
||||||
|
/* Get Screen Size *
|
||||||
|
* Returns: width in columns *
|
||||||
|
* height in rows */
|
||||||
|
char getsiz();
|
||||||
|
|
||||||
|
/* Move Cursor to Specified Position *
|
||||||
|
* Args: column - screen column (0 = left) *
|
||||||
|
* row - screen line (0 = top) */
|
||||||
|
void setpos();
|
||||||
|
|
||||||
|
/* Set Screen Mode *
|
||||||
|
* Args: char mode - screen mode *
|
||||||
|
* 0 = default text mode *
|
||||||
|
* Returns: $FF if Mode Invalid */
|
||||||
|
char setscr();
|
|
@ -1,5 +1,20 @@
|
||||||
;Screen Control Assembly Lanuage Routines for Oric-1
|
;Screen Control Assembly Lanuage Routines for Oric-1
|
||||||
|
|
||||||
|
SUBROUTINE _SCREEN
|
||||||
|
|
||||||
|
SMTEXT EQU $00 ;Default Text Screen
|
||||||
|
SMWIDE EQU $FF ;Wide Text Screen (Undefined)
|
||||||
|
|
||||||
|
;Set Screen Mode
|
||||||
|
SETSCR: CMP SMTEXT ;If Default Text Screen
|
||||||
|
BEQ GETSCR ;Return Return 0
|
||||||
|
LDA #$FF ;Else Return ERROR
|
||||||
|
RTS
|
||||||
|
;Else Return 0
|
||||||
|
;Get Screen Mode
|
||||||
|
GETSCR: LDA #0 ;Return 0 (Default Text Mode)
|
||||||
|
RTS
|
||||||
|
|
||||||
;Clear the Screen
|
;Clear the Screen
|
||||||
CLRSCR EQU $CC0A ;Basic CLS Routine (Atmos = $CCCE)
|
CLRSCR EQU $CC0A ;Basic CLS Routine (Atmos = $CCCE)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
* Screen Control Functions for Oric-1 *
|
* Screen Control Functions for Oric-1 *
|
||||||
***************************************/
|
***************************************/
|
||||||
|
|
||||||
|
/* Screen Modes for getscr() and setscr() */
|
||||||
|
#define SMTEXT $00 //System Default Text Mode
|
||||||
|
#define SMWIDE $FF //Wide Screen Text Mode (Unsupported)
|
||||||
|
|
||||||
/* Clear the Screen */
|
/* Clear the Screen */
|
||||||
void clrscn();
|
void clrscn();
|
||||||
|
|
||||||
|
@ -13,6 +17,10 @@ void crsrhm();
|
||||||
( cursor row */
|
( cursor row */
|
||||||
char getpos();
|
char getpos();
|
||||||
|
|
||||||
|
/* Get Screen Mode *
|
||||||
|
* Returns: char mode - Current Screen Mode */
|
||||||
|
char getscr();
|
||||||
|
|
||||||
/* Get Screen Size *
|
/* Get Screen Size *
|
||||||
* Returns: width in columns *
|
* Returns: width in columns *
|
||||||
* height in rows */
|
* height in rows */
|
||||||
|
@ -22,3 +30,9 @@ char getsiz();
|
||||||
* Args: column - screen column (0 = left) *
|
* Args: column - screen column (0 = left) *
|
||||||
* row - screen line (0 = top) */
|
* row - screen line (0 = top) */
|
||||||
void setpos();
|
void setpos();
|
||||||
|
|
||||||
|
/* Set Screen Mode *
|
||||||
|
* Args: char mode - screen mode *
|
||||||
|
* 0 = default text mode *
|
||||||
|
* Returns: $FF if Mode Invalid */
|
||||||
|
char setscr();
|
||||||
|
|
|
@ -23,7 +23,7 @@ char temp0, temp1, temp2, temp3; //Temporary Storage
|
||||||
|
|
||||||
//Memory Mapped I/O
|
//Memory Mapped I/O
|
||||||
char putcon; //Write Character to Console
|
char putcon; //Write Character to Console
|
||||||
char getcomn; //Read Character from Console
|
char getcon; //Read Character from Console
|
||||||
|
|
||||||
//System Subroutines
|
//System Subroutines
|
||||||
char polkey(); //Poll Console for character
|
char polkey(); //Poll Console for character
|
||||||
|
|
|
@ -1,6 +1,19 @@
|
||||||
;Screen Control Assembly Lanuage Routines for C02
|
;Screen Control Assembly Lanuage Routines for C02
|
||||||
;Skeleton Code for Systems with no Screen Control
|
;Skeleton Code for Systems with no Screen Control
|
||||||
|
|
||||||
|
SUBROUTINE _SCREEN
|
||||||
|
|
||||||
|
SMTEXT EQU $00 ;Default Text Screen
|
||||||
|
SMWIDE EQU $FF ;Wide Text Screen (Undefined)
|
||||||
|
|
||||||
|
;Set Screen Mode
|
||||||
|
SETSCR: CMP SMTEXT ;If Not Default Text
|
||||||
|
BEQ GETPOS ;Return Error
|
||||||
|
;Else Return 0
|
||||||
|
;Get Screen Mode
|
||||||
|
GETSCR: LDA #0 ;Return 0 (Default Text Mode)
|
||||||
|
RTS
|
||||||
|
|
||||||
;Clear the Screen
|
;Clear the Screen
|
||||||
CLRSCR: RTS ;No Action
|
CLRSCR: RTS ;No Action
|
||||||
|
|
||||||
|
@ -17,3 +30,4 @@ GETPOS: LDA #$FF ;Return Error
|
||||||
|
|
||||||
;Get Screen Size
|
;Get Screen Size
|
||||||
GETSIZ EQU GETPOS ;Return Error
|
GETSIZ EQU GETPOS ;Return Error
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
/********************************************
|
/***********************************
|
||||||
* screen - Screen Control Routines for C02 *
|
* Screen Control Routines for C02 *
|
||||||
********************************************/
|
***********************************/
|
||||||
|
|
||||||
|
/* Screen Modes for getscr() and setscr() *
|
||||||
|
* Invalid Modes have value $FF */
|
||||||
|
#define SMTEXT $00 //System Default Text Mode
|
||||||
|
#define SMWIDE $FF //Wide Screen Text Mode (Usuallu 80 Columns)
|
||||||
|
|
||||||
/* Clear the Screen */
|
/* Clear the Screen */
|
||||||
void clrscn();
|
void clrscn();
|
||||||
|
@ -18,7 +23,17 @@ char getpos();
|
||||||
* height in rows */
|
* height in rows */
|
||||||
char getsiz();
|
char getsiz();
|
||||||
|
|
||||||
/* Move Cursor to Specified Position *
|
/* Get Screen Mode *
|
||||||
* Args: column - screen column (0 = left) *
|
* Returns: char mode - Current Screen Mode */
|
||||||
* row - screen line (0 = top) */
|
char getscr();
|
||||||
|
|
||||||
|
/* Move Cursor to Specified Position *
|
||||||
|
* Args: char col - screen column (0 = left) *
|
||||||
|
* char row - screen line (0 = top) */
|
||||||
void setpos();
|
void setpos();
|
||||||
|
|
||||||
|
/* Set Screen Mode *
|
||||||
|
* Args: char mode - screen mode *
|
||||||
|
* 0 = default text mode *
|
||||||
|
* Returns: $FF if Mode Invalid */
|
||||||
|
char setscr();
|
||||||
|
|
|
@ -3,15 +3,17 @@
|
||||||
; external zero page locations SRCLO and SRCHI
|
; external zero page locations SRCLO and SRCHI
|
||||||
; and external locations RANDOM, RDSEED, TEMP0, TEMP1, and TEMP2.
|
; and external locations RANDOM, RDSEED, TEMP0, TEMP1, and TEMP2.
|
||||||
|
|
||||||
|
SUBROUTINE STDLIB
|
||||||
|
|
||||||
;abs(n) - Get ABSolute Value
|
;abs(n) - Get ABSolute Value
|
||||||
;Args: A = Number to get Absolute Value Of
|
;Args: A = Number to get Absolute Value Of
|
||||||
;Affects: C, N, Z
|
;Affects: C, N, Z
|
||||||
;Returns: A = Absolute Value of Argument
|
;Returns: A = Absolute Value of Argument
|
||||||
ABS: CMP #$80 ;If Negative (High Bit Set)
|
ABS: CMP #$80 ;If Negative (High Bit Set)
|
||||||
BCC ABSX ; Carry will Already be Set
|
BCC .ABSX ; Carry will Already be Set
|
||||||
EOR #$FF ; One's Complement
|
EOR #$FF ; One's Complement
|
||||||
ADC #$00 ; and Increment (Carry set by CMP)
|
ADC #$00 ; and Increment (Carry set by CMP)
|
||||||
ABSX: RTS
|
.ABSX RTS
|
||||||
|
|
||||||
;max(m,n) - Get MAXimum of Two Numbers
|
;max(m,n) - Get MAXimum of Two Numbers
|
||||||
;Args: A,Y = Numbers to Compare
|
;Args: A,Y = Numbers to Compare
|
||||||
|
@ -20,9 +22,9 @@ ABSX: RTS
|
||||||
;Returns: A = Larger of the Two Arguments
|
;Returns: A = Larger of the Two Arguments
|
||||||
MAX: STY TEMP0 ;Save Second Parameter
|
MAX: STY TEMP0 ;Save Second Parameter
|
||||||
CMP TEMP0 ;If First Parameter
|
CMP TEMP0 ;If First Parameter
|
||||||
BCC MAXX ; Greater than Second Parameter
|
BCC .MAXX ; Greater than Second Parameter
|
||||||
TYA ;Copy Second Parameter into Accumulator
|
TYA ;Copy Second Parameter into Accumulator
|
||||||
MAXX: RTS
|
.MAXX RTS
|
||||||
|
|
||||||
;min(m,n) - Get MINimum Get MAXimum of Two Numbers
|
;min(m,n) - Get MINimum Get MAXimum of Two Numbers
|
||||||
;Args: A,Y = Numbers to Compare
|
;Args: A,Y = Numbers to Compare
|
||||||
|
@ -31,9 +33,9 @@ MAXX: RTS
|
||||||
;Returns: A = Smaller of the Two Arguments
|
;Returns: A = Smaller of the Two Arguments
|
||||||
MIN: STY TEMP0 ;Save Second Parameter
|
MIN: STY TEMP0 ;Save Second Parameter
|
||||||
CMP TEMP0 ;If First Parameter
|
CMP TEMP0 ;If First Parameter
|
||||||
BCS MINX ; Less than Second Parameter
|
BCS .MINX ; Less than Second Parameter
|
||||||
TYA ;Copy Second Parameter into Accumulator
|
TYA ;Copy Second Parameter into Accumulator
|
||||||
MINX: RTS
|
.MINX RTS
|
||||||
|
|
||||||
;mult(m,n) - MULTiply Two Numbers
|
;mult(m,n) - MULTiply Two Numbers
|
||||||
;Args: A = Multiplicand
|
;Args: A = Multiplicand
|
||||||
|
@ -48,13 +50,13 @@ MULT: STA TEMP0 ;Store Multiplicand
|
||||||
STY TEMP1 ;Store Multiplier
|
STY TEMP1 ;Store Multiplier
|
||||||
;Multiply TEMP0 times TEMP1
|
;Multiply TEMP0 times TEMP1
|
||||||
MULTT: LDA #$00 ;Initialize Accumulator
|
MULTT: LDA #$00 ;Initialize Accumulator
|
||||||
BEQ MULTE ;Enter Loop
|
BEQ .MULTE ;Enter Loop
|
||||||
MULTA: CLC
|
.MULTA CLC
|
||||||
ADC TEMP0 ;Add Multiplicand
|
ADC TEMP0 ;Add Multiplicand
|
||||||
MULTL: ASL TEMP0 ;Shift Multiplicand Left
|
.MULTL ASL TEMP0 ;Shift Multiplicand Left
|
||||||
MULTE: LSR TEMP1 ;Shift Multiplier Right
|
.MULTE LSR TEMP1 ;Shift Multiplier Right
|
||||||
BCS MULTA ;If Bit Shifted Out, Add Multiplicand
|
BCS .MULTA ;If Bit Shifted Out, Add Multiplicand
|
||||||
BNE MULTL ;Loop if Any 1 Bits Left
|
BNE .MULTL ;Loop if Any 1 Bits Left
|
||||||
LDY TEMP2 ;Load Y with MSB
|
LDY TEMP2 ;Load Y with MSB
|
||||||
TAX ;and Copy LSB to X
|
TAX ;and Copy LSB to X
|
||||||
RTS
|
RTS
|
||||||
|
@ -73,13 +75,13 @@ DIV: STA TEMP0 ;Store Dividend
|
||||||
DIVT: LDA #$00 ;Clear Accumulator
|
DIVT: LDA #$00 ;Clear Accumulator
|
||||||
LDX #$07 ;Load Loop Counter
|
LDX #$07 ;Load Loop Counter
|
||||||
CLC
|
CLC
|
||||||
DIVL: ROL TEMP0 ;Shift Bit Out of Dividend
|
.DIVL ROL TEMP0 ;Shift Bit Out of Dividend
|
||||||
ROL ; into Accumulator
|
ROL ; into Accumulator
|
||||||
CMP TEMP1 ;If Accumulator
|
CMP TEMP1 ;If Accumulator
|
||||||
BCC DIVS ; >= Divisor
|
BCC .DIVS ; >= Divisor
|
||||||
SBC TEMP1 ;Subtract Divisor
|
SBC TEMP1 ;Subtract Divisor
|
||||||
DIVS: DEX ;Decrement Counter
|
.DIVS DEX ;Decrement Counter
|
||||||
BPL DIVL ; and Loop
|
BPL .DIVL ; and Loop
|
||||||
ROL TEMP0 ;Shift Result into Dividend
|
ROL TEMP0 ;Shift Result into Dividend
|
||||||
TAY ;Copy Remainder to Y Register
|
TAY ;Copy Remainder to Y Register
|
||||||
LDA TEMP0 ;Load Result into Accumulator
|
LDA TEMP0 ;Load Result into Accumulator
|
||||||
|
@ -90,9 +92,9 @@ DIVS: DEX ;Decrement Counter
|
||||||
;Affects A,N,Z,C
|
;Affects A,N,Z,C
|
||||||
RAND: LDA RANDOM ;Load Last Result
|
RAND: LDA RANDOM ;Load Last Result
|
||||||
ASL ;Shift the Seed
|
ASL ;Shift the Seed
|
||||||
BCC RANDX ;If a one was shifted out
|
BCC .RANDX ;If a one was shifted out
|
||||||
EOR #$1D ; Twiddle the bite
|
EOR #$1D ; Twiddle the bite
|
||||||
RANDX: STA RANDOM ;Save the Seed
|
.RANDX STA RANDOM ;Save the Seed
|
||||||
RTS
|
RTS
|
||||||
|
|
||||||
;Seed Pseudo-Random Number Generator
|
;Seed Pseudo-Random Number Generator
|
||||||
|
@ -100,25 +102,71 @@ RANDX: STA RANDOM ;Save the Seed
|
||||||
;Affects A,N,Z,C
|
;Affects A,N,Z,C
|
||||||
;Sets RANDOM
|
;Sets RANDOM
|
||||||
RANDS: ORA #$00 ;If Passed Value not 0
|
RANDS: ORA #$00 ;If Passed Value not 0
|
||||||
BNE RANDX ; Store in Seed and Return
|
BNE .RANDX ; Store in Seed and Return
|
||||||
LDA RDSEED ;Load System Generated Seed
|
LDA RDSEED ;Load System Generated Seed
|
||||||
BNE RANDX ;If Not 0, Store and Return
|
BNE .RANDX ;If Not 0, Store and Return
|
||||||
ADC #$01 ;Else Add 1 or 2
|
ADC #$01 ;Else Add 1 or 2
|
||||||
BNE RANDX ; then Store and Return
|
BNE .RANDX ; then Store and Return
|
||||||
|
|
||||||
;Return A Shifted Y Bytes to the Left
|
;swap(byte) - Swap Low and High Nybbles in Byte
|
||||||
;Affects A,Y,N,Z,C
|
;Args: A = Byte to Swap
|
||||||
;Affects A,Y,N,Z,C
|
;Affects Y,N,Z,C
|
||||||
SHIFTL: ASL ;Shift Byte to Left
|
;Returns: A = Swapped Byte
|
||||||
DEY ;Decrement Counter
|
SWAP: LDY #4 ;Set Count to 4 and Rotate Left
|
||||||
BNE SHIFTL ; and Loop if Not 0
|
|
||||||
|
;rotatl(byte,count) - Rotate byte by count Bits to the Left
|
||||||
|
;Args = Byte to Rotate
|
||||||
|
;Y = Number of Bits to Rotate
|
||||||
|
;Affects X,Y,N,Z,C
|
||||||
|
;Returns: A = Rotated Byte
|
||||||
|
ROTATL: INY ;Pre-Increment Counter
|
||||||
|
.ROTALL DEY ;Decrement Counter
|
||||||
|
BEQ .ROTATX ;If Not Zero
|
||||||
|
ASL ; Shift Left One Bit
|
||||||
|
ADC #0 ; Copy Carry into Bit 0
|
||||||
|
BNE .ROTALL ; If Not Zero, Loop
|
||||||
|
.ROTATX RTS
|
||||||
|
|
||||||
|
;rotatr(byte,count) - Shift byte by count Bits to the Right
|
||||||
|
;Args = Byte to Rotate
|
||||||
|
;Y = Number of Bits to Rotate
|
||||||
|
;Affects Y,N,Z,C
|
||||||
|
;Returns: A = Rotated Byte
|
||||||
|
ROTATR: INY ;Pre-Increment Counter
|
||||||
|
.ROTALR DEY ;Decrement Counter
|
||||||
|
BEQ .ROTATX ;If Not Zero
|
||||||
|
LSR ; Shift Right One Bit
|
||||||
|
BCC .ROTATS ; If Carry Set
|
||||||
|
ORA #$80 ; Copy Carry into Bit 7
|
||||||
|
.ROTATS BNE .ROTALR ; If Not Zero, Loop
|
||||||
RTS
|
RTS
|
||||||
|
|
||||||
;Return A Shifted Y Bytes to the Right
|
SHFTL4: LDY #4; ;Set Count to 4 and Shift Left
|
||||||
;Affects A,Y,N,Z,C
|
|
||||||
SHIFTR: LSR ;Shift Byte to Right
|
;shiftl(byte,count) - Shift byte by Count bits to the Left
|
||||||
DEY ;Decrement Counter
|
;Args = Byte to Shift
|
||||||
BNE SHIFTR ; and Loop if Not 0
|
;Y = Number of Bits to Rotate
|
||||||
|
;Affects Y,N,Z,C
|
||||||
|
;Returns: A = Shifted Byte
|
||||||
|
SHIFTL: INY ;Pre-Increment Counter
|
||||||
|
.SHIFLL DEY ;Decrement Counter
|
||||||
|
BEQ .SHIFTX ;If Not Zero
|
||||||
|
ASL ; Shift Byte to Left
|
||||||
|
BNE .SHIFLL ; and Loop if Not 0
|
||||||
|
.SHIFTX RTS
|
||||||
|
|
||||||
|
SHFTR4: LDY #4; ;Set Count to 4 and Shift Right
|
||||||
|
|
||||||
|
;shiftr(byte,count) - Shift byte by Count bits to the Right
|
||||||
|
;Args = Byte to Shift
|
||||||
|
;Y = Number of Bits to Rotate
|
||||||
|
;Affects Y,N,Z,C
|
||||||
|
;Returns: A = Shifted Byte
|
||||||
|
SHIFTR: INY ;Pre-Increment Counter
|
||||||
|
.SHIFLR DEY ;Decrement Counter
|
||||||
|
BEQ .SHIFTX ;If Not Zero
|
||||||
|
LSR ; Shift Byte to Right
|
||||||
|
BNE .SHIFLR ; and Loop if Not 0
|
||||||
RTS
|
RTS
|
||||||
|
|
||||||
;atoc(&s) - ASCII string TO Character
|
;atoc(&s) - ASCII string TO Character
|
||||||
|
@ -130,11 +178,11 @@ SHIFTR: LSR ;Shift Byte to Right
|
||||||
; Y = Number of Digits
|
; Y = Number of Digits
|
||||||
ATOC: JSR SETSRC ;Initialize Source String
|
ATOC: JSR SETSRC ;Initialize Source String
|
||||||
STY TEMP0 ;Initialize Result
|
STY TEMP0 ;Initialize Result
|
||||||
ATOCL: LDA (SRCLO),Y ;Get Next Character
|
.ATOCL LDA (SRCLO),Y ;Get Next Character
|
||||||
CMP #$30 ;If Less Than '0'
|
CMP #$30 ;If Less Than '0'
|
||||||
BCC ATOCX ; Exit
|
BCC .ATOCX ; Exit
|
||||||
CMP #$3A ;If Greater Than '9'
|
CMP #$3A ;If Greater Than '9'
|
||||||
BCS ATOCX ; Exit
|
BCS .ATOCX ; Exit
|
||||||
AND #$0F ;Convert to Binary Nybble
|
AND #$0F ;Convert to Binary Nybble
|
||||||
STA TEMP1 ; and Save It
|
STA TEMP1 ; and Save It
|
||||||
LDA TEMP0 ;Load Result
|
LDA TEMP0 ;Load Result
|
||||||
|
@ -145,8 +193,8 @@ ATOCL: LDA (SRCLO),Y ;Get Next Character
|
||||||
ADC TEMP1 ;Add Saved Nybble
|
ADC TEMP1 ;Add Saved Nybble
|
||||||
STA TEMP0 ; and Store Result
|
STA TEMP0 ; and Store Result
|
||||||
INY ;Increment Index
|
INY ;Increment Index
|
||||||
BPL ATOCL ; and Loop
|
BPL .ATOCL ; and Loop
|
||||||
ATOCX: LDA TEMP0 ;Load Result
|
.ATOCX LDA TEMP0 ;Load Result
|
||||||
RTS ;And Return
|
RTS ;And Return
|
||||||
|
|
||||||
;ctoa(n) - Character TO ASCII string
|
;ctoa(n) - Character TO ASCII string
|
||||||
|
@ -161,19 +209,19 @@ CTOA: JSR SETDST ;Initialize Source String
|
||||||
LDY #0 ;Initialize Index into String
|
LDY #0 ;Initialize Index into String
|
||||||
JSR CUBCD ;Convert Accumulator to Unpacked BCD
|
JSR CUBCD ;Convert Accumulator to Unpacked BCD
|
||||||
LDA TEMP2 ;Get MSB
|
LDA TEMP2 ;Get MSB
|
||||||
BEQ CTOA1 ;If Not Zero
|
BEQ .CTOA1 ;If Not Zero
|
||||||
JSR CTOAN ; Convert Low Nybble
|
JSR .CTOAN ; Convert Low Nybble
|
||||||
CTOA1: LDA TEMP1 ;Get Low Byte
|
.CTOA1 LDA TEMP1 ;Get Low Byte
|
||||||
BNE CTOA2 ;If Not Zero
|
BNE .CTOA2 ;If Not Zero
|
||||||
CMP TEMP2 ; and Hundreds
|
CMP TEMP2 ; and Hundreds
|
||||||
BEQ CTOA3 ; not Zero
|
BEQ .CTOA3 ; not Zero
|
||||||
CTOA2: JSR CTOAN ; Convert It
|
.CTOA2 JSR .CTOAN ; Convert It
|
||||||
CTOA3: LDA TEMP0 ;Get Low Byte
|
.CTOA3 LDA TEMP0 ;Get Low Byte
|
||||||
JSR CTOAN ;and Convert Low Nybble
|
JSR .CTOAN ;and Convert Low Nybble
|
||||||
LDA #$00
|
LDA #$00
|
||||||
BEQ CTOAX ;Terminate String
|
BEQ .CTOAX ;Terminate String
|
||||||
CTOAN: ORA #$30 ;Convert to ASCII digit
|
.CTOAN ORA #$30 ;Convert to ASCII digit
|
||||||
CTOAX: STA (DSTLO),Y ;Store in String
|
.CTOAX STA (DSTLO),Y ;Store in String
|
||||||
INY ;and Increment Offset
|
INY ;and Increment Offset
|
||||||
TYA ;Copy String Length to Accumulator
|
TYA ;Copy String Length to Accumulator
|
||||||
RTS
|
RTS
|
||||||
|
@ -207,23 +255,22 @@ UPBCD: LDA TEMP1 ;Get Low Byte
|
||||||
; TEMP2 = Hundreds Digit
|
; TEMP2 = Hundreds Digit
|
||||||
;Returns: A = Hundreds Digit
|
;Returns: A = Hundreds Digit
|
||||||
; X = 0
|
; X = 0
|
||||||
CVBCD: STA TEMP0 ;Save Binary Value
|
CVBCD: STA TEMP0 ;Save Binary Value
|
||||||
CVBCDT: LDA #0 ;Clear BCD Bytes
|
CVBCDT: LDA #0 ;Clear BCD Bytes
|
||||||
STA TEMP1
|
STA TEMP1
|
||||||
STA TEMP2
|
STA TEMP2
|
||||||
LDX #8 ;Process 8 bits of Binary
|
LDX #8 ;Process 8 bits of Binary
|
||||||
PHP ;Save Status Register
|
PHP ;Save Status Register
|
||||||
SEI ;Disable Interupts
|
SEI ;Disable Interupts
|
||||||
SED ;Set Decimal Mode
|
SED ;Set Decimal Mode
|
||||||
CVBCDL: ASL TEMP0 ;Shift High Bit into Carry
|
.CVBCDL ASL TEMP0 ;Shift High Bit into Carry
|
||||||
LDA TEMP1 ;Add BCD Low Byte to Itself
|
LDA TEMP1 ;Add BCD Low Byte to Itself
|
||||||
ADC TEMP1 ; Plus Bit Shifted out of Binary
|
ADC TEMP1 ; Plus Bit Shifted out of Binary
|
||||||
STA TEMP1 ; Effectively Multiplying It by 2
|
STA TEMP1 ; Effectively Multiplying It by 2
|
||||||
LDA TEMP2 ;Add BCD MSB to Itself
|
LDA TEMP2 ;Add BCD MSB to Itself
|
||||||
ADC TEMP2 ; Plus Bit Shifted out of Low Byte
|
ADC TEMP2 ; Plus Bit Shifted out of Low Byte
|
||||||
STA TEMP2 ; Effectively Multiplying It by 2
|
STA TEMP2 ; Effectively Multiplying It by 2
|
||||||
DEX ;Decrement Counter and
|
DEX ;Decrement Counter and
|
||||||
BNE CVBCDL ; Process Next Bit
|
BNE .CVBCDL ; Process Next Bit
|
||||||
PLP ;Restore Status Register
|
PLP ;Restore Status Register
|
||||||
RTS
|
RTS
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/************************************************
|
/***************************************************
|
||||||
* template - Template Library Routines for C02 *
|
* template.a02 - Template Module Routines for C02 *
|
||||||
************************************************/
|
***************************************************/
|
||||||
|
|
||||||
/* Function Description *
|
/* Function Description *
|
||||||
* Args: a - First Argument *
|
* Args: a - First Argument *
|
||||||
|
|
20
include/via.h02
Normal file
20
include/via.h02
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/* MOS 6522 VIA Registers */
|
||||||
|
|
||||||
|
struct via {
|
||||||
|
char iorb; //Input/Output Register B
|
||||||
|
char iora; //Input/Output Register A
|
||||||
|
char ddrb; //Data Direction Register B
|
||||||
|
char ddra; // Data Direction Register A
|
||||||
|
char t1cl; //T1 Low-Order Counter
|
||||||
|
char t1ch; //T1 High-Order Counter
|
||||||
|
char t1ll; //T1L-L | T1 Low-Order Latches
|
||||||
|
char t1lh; //T1 High-Order Latches
|
||||||
|
char t2cl; //T2 Low-Order Latches
|
||||||
|
char t2ch; //T2 High-Order Counter
|
||||||
|
char sr; //Shift Register
|
||||||
|
char acr; //Auxiliary Control Register
|
||||||
|
char pcr; //Peripheral Control Register
|
||||||
|
char ifr; //Interrupt Flag Register
|
||||||
|
char ier; //Interrupt Enable Register
|
||||||
|
char nhra; //Input/Output Register A (No Handshake)
|
||||||
|
}
|
|
@ -100,4 +100,6 @@ NEWLIN: LDX #0 ;Store 0
|
||||||
STX $D3 ;in Cursor Column and
|
STX $D3 ;in Cursor Column and
|
||||||
JMP $E8C3 ;Execute NXTLINE Routine
|
JMP $E8C3 ;Execute NXTLINE Routine
|
||||||
|
|
||||||
INCLUDE "../include/prbyte.a02" ;PRBYTE and PRHEX routines
|
;Print Zero-Terminated String
|
||||||
|
PUTSTR: TXA ;Copy LSB to Accumulator
|
||||||
|
JMP $CB1E ;Execute STROUT Routine
|
||||||
|
|
37
include/vic/keydef.a02
Normal file
37
include/vic/keydef.a02
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
;PETSCII Key Code Definitions
|
||||||
|
;for Commmodore 64 Computer
|
||||||
|
|
||||||
|
KEYBCK EQU $00 ;Backspace [N/A]
|
||||||
|
KEYBRK EQU $03 ;Break (RUN/STOP)
|
||||||
|
KEYCLR EQU $93 ;Clear (Shift-CLR/HOME)
|
||||||
|
KEYCPY EQU $00 ;Copy [N/A]
|
||||||
|
KEYDEL EQU $14 ;Delete
|
||||||
|
KEYDN EQU $11 ;Cursor Down
|
||||||
|
KEYESC EQU $00 ;Escape [N/A]
|
||||||
|
KEYFN1 EQU $85 ;F1 (F1/F2)
|
||||||
|
KEYFN2 EQU $89 ;F2 (Shift-F1/F2)
|
||||||
|
KEYFN3 EQU $86 ;F3 (F3/F4)
|
||||||
|
KEYFN4 EQU $8A ;F4 (Shift-F3/F4)
|
||||||
|
KEYFN5 EQU $87 ;F5 (F5/F6)
|
||||||
|
KEYFN6 EQU $8B ;F6 (Shift-F5/F6)
|
||||||
|
KEYFN7 EQU $88 ;F7 (F7/F8)
|
||||||
|
KEYFN8 EQU $8C ;F8 (Shift-F7/F8)
|
||||||
|
KEYFN9 EQU $00 ;F9 [N/A]
|
||||||
|
KEYFNA EQU $00 ;F10 [N/A]
|
||||||
|
KEYFNB EQU $00 ;F11 [N/A]
|
||||||
|
KEYFNC EQU $00 ;F12 [N/A]
|
||||||
|
KEYHLP EQU $84 ;Help [N/A]
|
||||||
|
KEYHOM EQU $13 ;Home (CLR/HOME)
|
||||||
|
KEYINS EQU $94 ;Insert (Shift-INS/DEL)
|
||||||
|
KEYLFT EQU $9D ;Cursor Left
|
||||||
|
KEYLNF EQU $00 ;Line Feed [N/A]
|
||||||
|
KEYRGT EQU $1D ;Cursor Right
|
||||||
|
KEYRTN EQU $0D ;Return
|
||||||
|
KEYRTS EQU $8D ;Shift-Return
|
||||||
|
KEYRUN EQU $00 ;Run (Shift-RUN/STOP)
|
||||||
|
KEYRVF EQU $92 ;Reverse Off
|
||||||
|
KEYRVS EQU $12 ;Reverse On
|
||||||
|
KEYSPS EQU $A0 ;Shifted Space
|
||||||
|
KEYTAB EQU $09 ;Tab
|
||||||
|
KEYTAS EQU $00 ;Shift-Tab [N/A]
|
||||||
|
KEYUP EQU $91 ;Cursor Up
|
37
include/vic/keydef.h02
Normal file
37
include/vic/keydef.h02
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/* PETSCII Key Code Definitions *
|
||||||
|
* for Commodore 64 Computer */
|
||||||
|
|
||||||
|
#define KEYBCK $00 //Backspace
|
||||||
|
#define KEYBRK $03 //Break (RUN/STOP)
|
||||||
|
#define KEYCLR $93 //Clear (Shift-CLR/HOME)
|
||||||
|
#define KEYCPY $00 //Copy [N/A]
|
||||||
|
#define KEYDEL $14 //Delete
|
||||||
|
#define KEYDN $11 //Cursor Down
|
||||||
|
#define KEYESC $00 //Escape [N/A]
|
||||||
|
#define KEYFN1 $85 //Function Key 1 (F1/F2)
|
||||||
|
#define KEYFN2 $89 //Function Key 2 (Shift-F1/F2)
|
||||||
|
#define KEYFN3 $86 //Function Key 3 (F3/F4)
|
||||||
|
#define KEYFN4 $8A //Function Key 4 (Shift-F3/F4)
|
||||||
|
#define KEYFN5 $87 //Function Key 5 (F5/F6)
|
||||||
|
#define KEYFN6 $8B //Function Key 6 (Shift-F5/F6)
|
||||||
|
#define KEYFN7 $88 //Function Key 7 (F7/F8)
|
||||||
|
#define KEYFN8 $8C //Function Key 8 (Shift-F7/F8) [HELP on C16]
|
||||||
|
#define KEYFN9 $00 //Function Key 9 [N/A]
|
||||||
|
#define KEYFNA $00 //Function Key 10 [N/A]
|
||||||
|
#define KEYFNB $00 //Function Key 11 [N/A]
|
||||||
|
#define KEYFNC $00 //Function Key 12 [N/A]
|
||||||
|
#define KEYHLP $84 //Help [N/A]
|
||||||
|
#define KEYHOM $13 //Home (CLR/HOME)
|
||||||
|
#define KEYINS $94 //Insert (Shift-INS/DEL)
|
||||||
|
#define KEYLFT $9D //Cursor Left
|
||||||
|
#define KEYLNF $00 //Line Feed (N/A)
|
||||||
|
#define KEYRGT $1D //Cursor Right
|
||||||
|
#define KEYRTN $0D //Return
|
||||||
|
#define KEYRTS $8D //Shift-Return
|
||||||
|
#define KEYRUN $00 //Run (Shift-RUN/STOP)
|
||||||
|
#define KEYRVF $92 //Reverse Off
|
||||||
|
#define KEYRVS $12 //Reverse On
|
||||||
|
#define KEYSPS $A0 //Shifted Space
|
||||||
|
#define KEYTAB $09 //Tab
|
||||||
|
#define KEYTAS $00 //Shift-Tab [N/A]
|
||||||
|
#define KEYUP $91 //Cursor Up
|
|
@ -1,5 +1,20 @@
|
||||||
;Screen Control Assembly Lanuage Routines for VIC-20
|
;Screen Control Assembly Lanuage Routines for VIC-20
|
||||||
|
|
||||||
|
SUBROUTINE _SCREEN
|
||||||
|
|
||||||
|
SMTEXT EQU $00 ;Default Text Screen
|
||||||
|
SMWIDE EQU $FF ;Wide Text Screen (Undefined)
|
||||||
|
|
||||||
|
;Set Screen Mode
|
||||||
|
SETSCR: CMP SMTEXT ;If Default Text Screen
|
||||||
|
BEQ GETSCR ;Return Return 0
|
||||||
|
LDA #$FF ;Else Return ERROR
|
||||||
|
RTS
|
||||||
|
;Else Return 0
|
||||||
|
;Get Screen Mode
|
||||||
|
GETSCR: LDA #0 ;Return 0 (Default Text Mode)
|
||||||
|
RTS
|
||||||
|
|
||||||
;Clear the Screen
|
;Clear the Screen
|
||||||
CLRSCR EQU $E55F ;Aliased to CLSR Routine
|
CLRSCR EQU $E55F ;Aliased to CLSR Routine
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
* Screen Control Functions for VIC-20 *
|
* Screen Control Functions for VIC-20 *
|
||||||
***************************************/
|
***************************************/
|
||||||
|
|
||||||
|
/* Screen Modes for getscr() and setscr() */
|
||||||
|
#define SMTEXT $00 //System Default Text Mode
|
||||||
|
#define SMWIDE $FF //Wide Screen Text Mode (Unsupported)
|
||||||
|
|
||||||
/* Clear the Screen */
|
/* Clear the Screen */
|
||||||
void clrscn();
|
void clrscn();
|
||||||
|
|
||||||
|
@ -13,6 +17,10 @@ void crsrhm();
|
||||||
( cursor row */
|
( cursor row */
|
||||||
char getpos();
|
char getpos();
|
||||||
|
|
||||||
|
/* Get Screen Mode *
|
||||||
|
* Returns: char mode - Current Screen Mode */
|
||||||
|
char getscr();
|
||||||
|
|
||||||
/* Get Screen Size *
|
/* Get Screen Size *
|
||||||
* Returns: width in columns *
|
* Returns: width in columns *
|
||||||
* height in rows */
|
* height in rows */
|
||||||
|
@ -22,3 +30,9 @@ char getsiz();
|
||||||
* Args: column - screen column (0 = left) *
|
* Args: column - screen column (0 = left) *
|
||||||
* row - screen line (0 = top) */
|
* row - screen line (0 = top) */
|
||||||
void setpos();
|
void setpos();
|
||||||
|
|
||||||
|
/* Set Screen Mode *
|
||||||
|
* Args: char mode - screen mode *
|
||||||
|
* 0 = default text mode *
|
||||||
|
* Returns: $FF if Mode Invalid */
|
||||||
|
char setscr();
|
||||||
|
|
|
@ -16,3 +16,4 @@ BASIC: DC $0C, $10 ;Pointer to Next Line
|
||||||
DC $00, $00 ;End of Basic Program
|
DC $00, $00 ;End of Basic Program
|
||||||
|
|
||||||
INCLUDE "../include/vic.a02" ;Include VIC 20 Common Code
|
INCLUDE "../include/vic.a02" ;Include VIC 20 Common Code
|
||||||
|
INCLUDE "../include/prbyte.a02" ;PRBYTE and PRHEX routines
|
|
@ -16,3 +16,4 @@ BASIC: DC $0C, $04 ;Pointer to Next Line
|
||||||
DC $00, $00 ;End of Basic Program
|
DC $00, $00 ;End of Basic Program
|
||||||
|
|
||||||
INCLUDE "../include/vic.a02" ;Include VIC 20 Common Code
|
INCLUDE "../include/vic.a02" ;Include VIC 20 Common Code
|
||||||
|
INCLUDE "../include/prbyte.a02" ;PRBYTE and PRHEX routines
|
|
@ -16,3 +16,4 @@ BASIC: DC $0C, $12 ;Pointer to Next Line
|
||||||
DC $00, $00 ;End of Basic Program
|
DC $00, $00 ;End of Basic Program
|
||||||
|
|
||||||
INCLUDE "../include/vic.a02" ;Include VIC 20 Common Code
|
INCLUDE "../include/vic.a02" ;Include VIC 20 Common Code
|
||||||
|
INCLUDE "../include/prbyte.a02" ;PRBYTE and PRHEX routines
|
455
src/c02.c
455
src/c02.c
|
@ -1,227 +1,228 @@
|
||||||
/**************************************************************
|
/**************************************************************
|
||||||
* C02 Compiler - (C) 2013 Curtis F Kaylor *
|
* C02 Compiler - (C) 2013 Curtis F Kaylor *
|
||||||
* *
|
* *
|
||||||
* C02 is a simpified C-like language designed for the 6502 *
|
* C02 is a simpified C-like language designed for the 6502 *
|
||||||
* *
|
* *
|
||||||
* This Compiler generates crasm compatible assembly language *
|
* This Compiler generates crasm compatible assembly language *
|
||||||
* *
|
* *
|
||||||
**************************************************************/
|
**************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "common.h" //Common Code used by all Modules
|
#include "common.h" //Common Code used by all Modules
|
||||||
#include "files.h" //Open and Close Files
|
#include "files.h" //Open and Close Files
|
||||||
#include "asm.h" //Write out Assembly Language
|
#include "asm.h" //Write out Assembly Language
|
||||||
#include "parse.h" //General Code Parsing
|
#include "parse.h" //General Code Parsing
|
||||||
#include "vars.h" //Variable Parsing, Lookup, and Allocation
|
#include "vars.h" //Variable Parsing, Lookup, and Allocation
|
||||||
#include "expr.h" //Expression Parsing
|
#include "expr.h" //Expression Parsing
|
||||||
#include "label.h" //Label Parsing, Generation, and Lookup
|
#include "label.h" //Label Parsing, Generation, and Lookup
|
||||||
#include "cond.h" //Conditional Parsing
|
#include "cond.h" //Conditional Parsing
|
||||||
#include "stmnt.h" //Statement Compiling Code
|
#include "stmnt.h" //Statement Compiling Code
|
||||||
#include "dclrtn.h" //Statement Compiling Code
|
#include "dclrtn.h" //Statement Compiling Code
|
||||||
#include "include.h" //Include File Parsing
|
#include "include.h" //Include File Parsing
|
||||||
|
|
||||||
/* Initilize Compiler Variables */
|
/* Initilize Compiler Variables */
|
||||||
void init(void) {
|
void init(void) {
|
||||||
initim(); //Initialize Elapsed Time
|
DEBUG("Initializing Compiler Variables\n",0)
|
||||||
DEBUG("Initializing Compiler Variables\n",0)
|
concnt = 0; //Number of Constants Defined
|
||||||
concnt = 0; //Number of Constants Defined
|
varcnt = 0; //Number of Variables in Table
|
||||||
varcnt = 0; //Number of Variables in Table
|
lblcnt = 0; //Number of Labels in stack
|
||||||
lblcnt = 0; //Number of Labels in stack
|
padcnt = 0; //Number of Padding Bytes at End
|
||||||
padcnt = 0; //Number of Padding Bytes at End
|
curcol = 0; //Current Column in Source Code
|
||||||
curcol = 0; //Current Column in Source Code
|
curlin = 0; //Current Line in Source Code
|
||||||
curlin = 0; //Current Line in Source Code
|
alcvar = TRUE; //Allocate Variables Flag
|
||||||
alcvar = TRUE; //Allocate Variables Flag
|
inblck = FALSE; //Multiline Block Flag
|
||||||
inblck = FALSE; //Multiline Block Flag
|
infunc = FALSE; //Inside Function Definition
|
||||||
infunc = FALSE; //Inside Function Definition
|
xstmnt[0] = 0; //Expected Statement
|
||||||
xstmnt[0] = 0; //Expected Statement
|
nxtwrd[0] = 0; //Next Word (from DEFINE lookup)
|
||||||
nxtwrd[0] = 0; //Next Word (from DEFINE lookup)
|
nxtptr = 0; //Pointer to next character in nxtwrd
|
||||||
nxtptr = 0; //Pointer to next character in nxtwrd
|
vrwrtn = FALSE; //Variables Written Flag
|
||||||
vrwrtn = FALSE; //Variables Written Flag
|
rambas = 0; //RAM Base Address
|
||||||
rambas = 0; //RAM Base Address
|
wrtbas = 0; //Write Base Address
|
||||||
wrtbas = 0; //Write Base Address
|
zpaddr = 0; //Current Zero-Page Address
|
||||||
zpaddr = 0; //Current Zero-Page Address
|
invasc = FALSE; //Invert ASCII Flag
|
||||||
invasc = FALSE; //Invert ASCII Flag
|
mskasc = FALSE; //Set High Bit Flag
|
||||||
mskasc = FALSE; //Set High Bit Flag
|
fcase = FALSE; //First Case Statement Flag
|
||||||
fcase = FALSE; //First Case Statement Flag
|
wrtofs[0] = 0; //Write Offset
|
||||||
wrtofs[0] = 0; //Write Offset
|
xsnvar[0] = 0; //Assigned X Variable Name
|
||||||
xsnvar[0] = 0; //Assigned X Variable Name
|
ysnvar[0] = 0; //Assigned Y Variable Name
|
||||||
ysnvar[0] = 0; //Assigned Y Variable Name
|
subcnt = 0; //Include Subdirectories
|
||||||
subcnt = 0; //Include Subdirectories
|
strcpy(cputyp, CPUARG); //Set CPU Type to Default Value
|
||||||
strcpy(cputyp, CPUARG); //Set CPU Type to Default Value
|
strcpy(incdir, "../include/");
|
||||||
strcpy(incdir, "../include/");
|
}
|
||||||
}
|
|
||||||
|
/* Parse Pointer Dereference Assignment */
|
||||||
/* Parse Pointer Dereference Assignment */
|
void ppntr(void) {
|
||||||
void ppntr(void) {
|
lsrtrn = FALSE; //Clear RETURN flag
|
||||||
lsrtrn = FALSE; //Clear RETURN flag
|
if (xstmnt[0]) ERROR("Expected '%s' statement\n", xstmnt, EXIT_FAILURE)
|
||||||
if (xstmnt[0]) ERROR("Expected '%s' statement\n", xstmnt, EXIT_FAILURE)
|
prcasp(';');
|
||||||
prcasp(';');
|
}
|
||||||
}
|
|
||||||
|
/* Reads and parses the next Word in Source File */
|
||||||
/* Reads and parses the next Word in Source File */
|
void pword(void) {
|
||||||
void pword(void) {
|
lsrtrn = FALSE; //Clear RETURN flag
|
||||||
lsrtrn = FALSE; //Clear RETURN flag
|
getwrd();
|
||||||
getwrd();
|
DEBUG("Parsing Word '%s'\n", word)
|
||||||
DEBUG("Parsing Word '%s'\n", word)
|
if (xstmnt[0]) {
|
||||||
if (xstmnt[0]) {
|
if (wordis(xstmnt)) xstmnt[0] = 0; //Clear xstmnt
|
||||||
if (wordis(xstmnt)) xstmnt[0] = 0; //Clear xstmnt
|
else ERROR("Expected '%s' statement\n", xstmnt, EXIT_FAILURE)
|
||||||
else ERROR("Expected '%s' statement\n", xstmnt, EXIT_FAILURE)
|
}
|
||||||
}
|
if (!pmodfr() && !ptype(MTNONE)) pstmnt(); //Parse Statement
|
||||||
if (!pmodfr() && !ptype(MTNONE)) pstmnt(); //Parse Statement
|
}
|
||||||
}
|
|
||||||
|
/* Process a directive */
|
||||||
/* Process a directive */
|
void pdrctv(void) {
|
||||||
void pdrctv(void) {
|
skpchr(); //skip '#'
|
||||||
skpchr(); //skip '#'
|
CCMNT('#');
|
||||||
CCMNT('#');
|
getwrd(); //read directive into word
|
||||||
getwrd(); //read directive into word
|
DEBUG("Processing directive '%s'\n", word)
|
||||||
DEBUG("Processing directive '%s'\n", word)
|
if (wordis("DEFINE")) pdefin(); //Parse Define
|
||||||
if (wordis("DEFINE")) pdefin(); //Parse Define
|
else if (wordis("INCLUDE")) pincfl(); //Parse Include File
|
||||||
else if (wordis("INCLUDE")) pincfl(); //Parse Include File
|
else if (wordis("ERROR")) ERROR("Error \n", 0, EXIT_FAILURE)
|
||||||
else if (wordis("ERROR")) ERROR("Error \n", 0, EXIT_FAILURE)
|
else if (wordis("PRAGMA")) pprgma();
|
||||||
else if (wordis("PRAGMA")) pprgma();
|
else ERROR("Illegal directive %s encountered\n", word, EXIT_FAILURE)
|
||||||
else ERROR("Illegal directive %s encountered\n", word, EXIT_FAILURE)
|
}
|
||||||
}
|
|
||||||
|
void prolog(void) {
|
||||||
void prolog(void) {
|
DEBUG("Writing Assembly Prolog\n", 0)
|
||||||
DEBUG("Writing Assembly Prolog\n", 0)
|
asmlin(CPUOP,cputyp);
|
||||||
asmlin(CPUOP,cputyp);
|
setcmt("Program ");
|
||||||
setcmt("Program ");
|
addcmt(srcnam);
|
||||||
addcmt(srcnam);
|
cmtlin();
|
||||||
cmtlin();
|
}
|
||||||
}
|
|
||||||
|
void epilog(void) {
|
||||||
void epilog(void) {
|
if (!vrwrtn) wvrtbl(); //Write Variable Table
|
||||||
if (!vrwrtn) wvrtbl(); //Write Variable Table
|
if (padcnt) {
|
||||||
if (padcnt) {
|
SCMNT("PADDING BYTES")
|
||||||
SCMNT("PADDING BYTES")
|
sprintf(word, "$%hhX", padcnt);
|
||||||
sprintf(word, "$%hhX", padcnt);
|
asmlin(STROP, word);
|
||||||
asmlin(STROP, word);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/* Compile Source Code*/
|
||||||
/* Compile Source Code*/
|
void compile(void) {
|
||||||
void compile(void) {
|
DEBUG("Starting Compilation\n", 0)
|
||||||
DEBUG("Starting Compilation\n", 0)
|
prolog();
|
||||||
prolog();
|
phdrfl(); //Process Header File specified on Command Line
|
||||||
phdrfl(); //Process Header File specified on Command Line
|
skpchr();
|
||||||
skpchr();
|
DEBUG("Parsing Code\n", 0)
|
||||||
DEBUG("Parsing Code\n", 0)
|
while (TRUE) {
|
||||||
while (TRUE) {
|
skpspc();
|
||||||
skpspc();
|
if (match(EOF)) break; //Stop Parsing (End of File)
|
||||||
if (match(EOF)) break; //Stop Parsing (End of File)
|
else if (match('}')) endblk(TRUE); //End Multi-Line Program Block
|
||||||
else if (match('}')) endblk(TRUE); //End Multi-Line Program Block
|
else if (match('#')) pdrctv(); //Parse Directive
|
||||||
else if (match('#')) pdrctv(); //Parse Directive
|
else if (match('/')) skpcmt(TRUE); //Skip Comment
|
||||||
else if (match('/')) skpcmt(TRUE); //Skip Comment
|
else if (match('*')) ppntr(); //Parse Pointer
|
||||||
else if (match('*')) ppntr(); //Parse Pointer
|
else if (isalph()) pword(); //Parse Word
|
||||||
else if (isalph()) pword(); //Parse Word
|
else ERROR("Unexpected character '%c'\n", nxtchr, EXIT_FAILURE)
|
||||||
else ERROR("Unexpected character '%c'\n", nxtchr, EXIT_FAILURE)
|
}
|
||||||
}
|
epilog();
|
||||||
epilog();
|
}
|
||||||
}
|
|
||||||
|
/* Display "Usage" text and exit*/
|
||||||
/* Display "Usage" text and exit*/
|
void usage(void) {
|
||||||
void usage(void) {
|
printf("Usage: c02 sourcefile.c02\n");
|
||||||
printf("Usage: c02 sourcefile.c02\n");
|
exit(EXIT_FAILURE);
|
||||||
exit(EXIT_FAILURE);
|
}
|
||||||
}
|
|
||||||
|
/* Parse Command Line Option */
|
||||||
/* Parse Command Line Option */
|
int popt(int arg, int argc, char *argv[]) {
|
||||||
int popt(int arg, int argc, char *argv[]) {
|
char argstr[32]; //Argument String
|
||||||
char argstr[32]; //Argument String
|
char opt; //Option
|
||||||
char opt; //Option
|
char optarg[32]; //Option Argument
|
||||||
char optarg[32]; //Option Argument
|
strncpy (argstr, argv[arg], 31);
|
||||||
strncpy (argstr, argv[arg], 31);
|
if (strlen(argstr) != 2) ERROR("malformed option %s\n", argstr, EXIT_FAILURE)
|
||||||
if (strlen(argstr) != 2) ERROR("malformed option %s\n", argstr, EXIT_FAILURE)
|
opt = toupper(argstr[1]);
|
||||||
opt = toupper(argstr[1]);
|
if (strchr("CHS", opt)) {
|
||||||
if (strchr("CHS", opt)) {
|
if (++arg >= argc) ERROR("Option -%c requires an argument\n", opt, EXIT_FAILURE)
|
||||||
if (++arg >= argc) ERROR("Option -%c requires an argument\n", opt, EXIT_FAILURE)
|
strncpy(optarg, argv[arg], 31);
|
||||||
strncpy(optarg, argv[arg], 31);
|
}
|
||||||
}
|
DEBUG("Processing Command Line Option -%c\n", argstr[1])
|
||||||
DEBUG("Processing Command Line Option -%c\n", argstr[1])
|
switch (opt) {
|
||||||
switch (opt) {
|
case 'D':
|
||||||
case 'C':
|
debug = TRUE;
|
||||||
strcpy(cputyp, optarg);
|
DEBUG("Debug output enable\n", 0)
|
||||||
DEBUG("CPU Type set to '%s'\n", cputyp)
|
break;
|
||||||
break;
|
case 'C':
|
||||||
case 'H':
|
strcpy(cputyp, optarg);
|
||||||
strcpy(hdrnam, optarg);
|
DEBUG("CPU Type set to '%s'\n", cputyp)
|
||||||
DEBUG("Header Name set to '%s'\n", hdrnam)
|
break;
|
||||||
break;
|
case 'H':
|
||||||
case 'S':
|
strcpy(hdrnam, optarg);
|
||||||
strcpy(subdir[subcnt], optarg);
|
DEBUG("Header Name set to '%s'\n", hdrnam)
|
||||||
DEBUG("subdir[%d] ", subcnt)
|
break;
|
||||||
DEBUG("set to '%s'\n", subdir[subcnt])
|
case 'S':
|
||||||
subcnt++;
|
strcpy(subdir[subcnt], optarg);
|
||||||
break;
|
DEBUG("subdir[%d] ", subcnt)
|
||||||
default:
|
DEBUG("set to '%s'\n", subdir[subcnt])
|
||||||
ERROR("Illegal option -%c\n", opt, EXIT_FAILURE)
|
subcnt++;
|
||||||
}
|
break;
|
||||||
return arg;
|
default:
|
||||||
}
|
ERROR("Illegal option -%c\n", opt, EXIT_FAILURE)
|
||||||
|
}
|
||||||
/* Parse Command Line Arguments *
|
return arg;
|
||||||
* Sets: srcnam - Source File Name (from first arg) *
|
}
|
||||||
* outnam - Output File Name (from optional second arg) */
|
|
||||||
void pargs(int argc, char *argv[]) {
|
/* Parse Command Line Arguments *
|
||||||
int arg;
|
* Sets: srcnam - Source File Name (from first arg) *
|
||||||
srcnam[0] = 0;
|
* outnam - Output File Name (from optional second arg) */
|
||||||
outnam[0] = 0;
|
void pargs(int argc, char *argv[]) {
|
||||||
DEBUG("Parsing %d arguments\n", argc)
|
int arg;
|
||||||
if (argc == 0) usage(); //at least one argument is required
|
srcnam[0] = 0;
|
||||||
for (arg = 1; arg<argc; arg++) {
|
outnam[0] = 0;
|
||||||
DEBUG("Parsing argument %d\n", arg);
|
DEBUG("Parsing %d arguments\n", argc)
|
||||||
if (argv[arg][0] == '-') arg = popt(arg, argc, argv); //Process Command Line Option
|
if (argc == 0) usage(); //at least one argument is required
|
||||||
else if (srcnam[0] == 0) strcpy(srcnam, argv[arg]); //set Source File Name to first arg
|
for (arg = 1; arg<argc; arg++) {
|
||||||
else if (outnam[0] == 0) strcpy(outnam, argv[arg]); //set Out File Name to second arg
|
DEBUG("Parsing argument %d\n", arg);
|
||||||
else ERROR("Unexpected argument '%s'\n", argv[arg], EXIT_FAILURE)
|
if (argv[arg][0] == '-') arg = popt(arg, argc, argv); //Process Command Line Option
|
||||||
}
|
else if (srcnam[0] == 0) strcpy(srcnam, argv[arg]); //set Source File Name to first arg
|
||||||
if (srcnam[0]) DEBUG("srcnam set to '%s'\n", srcnam)
|
else if (outnam[0] == 0) strcpy(outnam, argv[arg]); //set Out File Name to second arg
|
||||||
else ERROR("Error: Source file not specified\n", 0, EXIT_FAILURE)
|
else ERROR("Unexpected argument '%s'\n", argv[arg], EXIT_FAILURE)
|
||||||
if (outnam[0]) DEBUG("outnam set to '%s'\n", outnam)
|
}
|
||||||
}
|
if (srcnam[0]) DEBUG("srcnam set to '%s'\n", srcnam)
|
||||||
|
else ERROR("Error: Source file not specified\n", 0, EXIT_FAILURE)
|
||||||
/* Validate CPU Type *
|
if (outnam[0]) DEBUG("outnam set to '%s'\n", outnam)
|
||||||
* Uses: cputype *
|
}
|
||||||
* Sets: cmos */
|
|
||||||
void chkcpu(void) {
|
/* Validate CPU Type *
|
||||||
if (strcmp(cputyp, "6502") == 0) cmos = FALSE;
|
* Uses: cputype *
|
||||||
else if (strcmp(cputyp, "65C02") == 0) cmos = TRUE;
|
* Sets: cmos */
|
||||||
else ERROR("Invalid CPU Type %s\n", cputyp, EXIT_FAILURE)
|
void chkcpu(void) {
|
||||||
}
|
if (strcmp(cputyp, "6502") == 0) cmos = FALSE;
|
||||||
|
else if (strcmp(cputyp, "65C02") == 0) cmos = TRUE;
|
||||||
|
else ERROR("Invalid CPU Type %s\n", cputyp, EXIT_FAILURE)
|
||||||
int main(int argc, char *argv[]) {
|
}
|
||||||
debug = TRUE; //Output Debug Info
|
|
||||||
gencmt = TRUE; //Generate Assembly Language Comments
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
printf("C02 Compiler (C) 2012 Curtis F Kaylor\n" );
|
debug = FALSE; //Do Not Output Debug Info by Default
|
||||||
|
gencmt = TRUE; //Generate Assembly Language Comments
|
||||||
init(); //Initialize Global Variables
|
|
||||||
|
printf("C02 Compiler (C) 2012 Curtis F Kaylor\n" );
|
||||||
pargs(argc, argv); //Parse Command Line Arguments
|
|
||||||
chkcpu(); //Validate CPU Type
|
init(); //Initialize Global Variables
|
||||||
|
|
||||||
opnsrc(); //Open Source File
|
pargs(argc, argv); //Parse Command Line Arguments
|
||||||
opnout(); //Open Output File
|
chkcpu(); //Validate CPU Type
|
||||||
opnlog(); //Open Log File
|
|
||||||
|
opnsrc(); //Open Source File
|
||||||
setsrc(); //Set Input to Source File
|
opnout(); //Open Output File
|
||||||
|
opnlog(); //Open Log File
|
||||||
compile();
|
|
||||||
|
setsrc(); //Set Input to Source File
|
||||||
logstc();
|
|
||||||
logcon();
|
compile();
|
||||||
loglab();
|
|
||||||
|
logstc();
|
||||||
clssrc(); //Close Source File
|
logcon();
|
||||||
clsout(); //Close Output File
|
loglab();
|
||||||
clslog(); //Close Log File
|
|
||||||
}
|
clssrc(); //Close Source File
|
||||||
|
clsout(); //Close Output File
|
||||||
|
clslog(); //Close Log File
|
||||||
|
}
|
||||||
|
|
104
src/common.c
104
src/common.c
|
@ -1,60 +1,44 @@
|
||||||
/*************************************
|
/*************************************
|
||||||
* C02 Common Definitions & Routines *
|
* C02 Common Definitions & Routines *
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <time.h>
|
#include "common.h"
|
||||||
#include "common.h"
|
|
||||||
|
/* Error - Print Input File name & position and exit */
|
||||||
struct timespec curtim; //Current Time
|
void exterr(int errnum) {
|
||||||
|
fprintf(stderr, "Line %d Column %d of File %s\n", curlin, curcol, inpnam);
|
||||||
/* Error - Print Input File name & position and exit */
|
exit(errnum);
|
||||||
void exterr(int errnum) {
|
}
|
||||||
fprintf(stderr, "Line %d Column %d of File %s\n", curlin, curcol, inpnam);
|
|
||||||
exit(errnum);
|
/* Error - print "Expected" error message *
|
||||||
}
|
and exit with general failure code *
|
||||||
|
Args: expected - Description of what was expected */
|
||||||
/* Error - print "Expected" error message *
|
void expctd(char *expstr) {
|
||||||
and exit with general failure code *
|
fprintf(stderr, "Expected %s, but found '%c'\n", expstr, nxtchr);
|
||||||
Args: expected - Description of what was expected */
|
exterr(EXIT_FAILURE);
|
||||||
void expctd(char *expstr) {
|
}
|
||||||
fprintf(stderr, "Expected %s, but found '%c'\n", expstr, nxtchr);
|
|
||||||
exterr(EXIT_FAILURE);
|
/* Print current position in file */
|
||||||
}
|
void prtpos(void) { if (inpnam[0]) printf("(%s: %d,%d) ", inpnam, curlin, curcol); }
|
||||||
|
|
||||||
/* Print current position in file */
|
/* Set comment to string */
|
||||||
void prtpos(void) { if (inpnam[0]) printf("(%s: %d,%d) ", inpnam, curlin, curcol); }
|
void setcmt(char *s) { strcpy(cmtasm, s); }
|
||||||
|
|
||||||
/* Initialize elapsed time counter */
|
/* Append string to comment */
|
||||||
void initim(void) {
|
void addcmt(char *s) {
|
||||||
timespec_get (&curtim, TIME_UTC);
|
if (strlen(cmtasm)+strlen(s)<73) strcat(cmtasm, s);
|
||||||
bgntim = curtim.tv_sec;
|
}
|
||||||
}
|
|
||||||
|
/* Append character to comment */
|
||||||
/* Print elapsed time */
|
void chrcmt(char c) {
|
||||||
void prttim(void) {
|
if (strlen(cmtasm)>72) return;
|
||||||
timespec_get (&curtim, TIME_UTC);
|
if (cmtasm[0] == 0 && c == ' ') return;
|
||||||
printf("[%d", curtim.tv_sec - bgntim);
|
int i = strlen(cmtasm);
|
||||||
printf(".%06d]",curtim.tv_nsec/1000);
|
cmtasm[i++] = c;
|
||||||
}
|
cmtasm[i] = 0;
|
||||||
|
}
|
||||||
/* Set comment to string */
|
|
||||||
void setcmt(char *s) { strcpy(cmtasm, s); }
|
|
||||||
|
|
||||||
/* Append string to comment */
|
|
||||||
void addcmt(char *s) {
|
|
||||||
if (strlen(cmtasm)+strlen(s)<73) strcat(cmtasm, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Append character to comment */
|
|
||||||
void chrcmt(char c) {
|
|
||||||
if (strlen(cmtasm)>72) return;
|
|
||||||
if (cmtasm[0] == 0 && c == ' ') return;
|
|
||||||
int i = strlen(cmtasm);
|
|
||||||
cmtasm[i++] = c;
|
|
||||||
cmtasm[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
194
src/common.h
194
src/common.h
|
@ -1,98 +1,96 @@
|
||||||
/*************************************
|
/*************************************
|
||||||
* C02 Common Definitions & Routines *
|
* C02 Common Definitions & Routines *
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
#define FNAMLEN 255 //Maximum File Name Length
|
#define FNAMLEN 255 //Maximum File Name Length
|
||||||
#define LINELEN 255 //Maximum Input/Output Line Length
|
#define LINELEN 255 //Maximum Input/Output Line Length
|
||||||
#define CONLEN 6 //Maximum Constant Name Length
|
#define CONLEN 6 //Maximum Constant Name Length
|
||||||
#define MAXCON 255 //Maximum Number of Constants
|
#define MAXCON 255 //Maximum Number of Constants
|
||||||
#define STCLEN 6 //Maximum Struct Name Length
|
#define STCLEN 6 //Maximum Struct Name Length
|
||||||
#define MAXSTC 32 //Maximum Number of Stuctures
|
#define MAXSTC 32 //Maximum Number of Stuctures
|
||||||
#define STMLEN 6 //Maximum Struct Member Name Length
|
#define STMLEN 6 //Maximum Struct Member Name Length
|
||||||
#define MAXSTM 255 //Maximum Number of Stucture Members
|
#define MAXSTM 255 //Maximum Number of Stucture Members
|
||||||
#define VARLEN 6 //Maximum Variable Name Length
|
#define VARLEN 6 //Maximum Variable Name Length
|
||||||
#define MAXVAR 255 //Maximum Number of Variables
|
#define MAXVAR 255 //Maximum Number of Variables
|
||||||
#define MAXTRM 16 //Maximum Terms in Stack
|
#define MAXTRM 16 //Maximum Terms in Stack
|
||||||
#define DATASPC 4096 //Space to Allocate for Variable Data
|
#define DATASPC 4096 //Space to Allocate for Variable Data
|
||||||
#define SUBMAX 4 //Maximum Number of Sub Directories
|
#define SUBMAX 4 //Maximum Number of Sub Directories
|
||||||
|
|
||||||
#define LABLEN 6 //Maximum Program Label Length
|
#define LABLEN 6 //Maximum Program Label Length
|
||||||
#define MAXLAB 255 //Maximum Number of Program Labels
|
#define MAXLAB 255 //Maximum Number of Program Labels
|
||||||
|
|
||||||
#define LBLLEN 6 //Maximum Label Length
|
#define LBLLEN 6 //Maximum Label Length
|
||||||
#define LBLFMT "L_%04d" //Label Format
|
#define LBLFMT "L_%04d" //Label Format
|
||||||
#define LABSFX ":" //Label Suffix
|
#define LABSFX ":" //Label Suffix
|
||||||
#define MAXLBL 15 //Maximum Number of Labels (Nesting Depth)
|
#define MAXLBL 15 //Maximum Number of Labels (Nesting Depth)
|
||||||
#define LOCPFX "." //Local Variable Prefix
|
#define LOCPFX "." //Local Variable Prefix
|
||||||
|
|
||||||
#define CPUOP "PROCESSOR" //Target CPU Pseudo-Operator
|
#define CPUOP "PROCESSOR" //Target CPU Pseudo-Operator
|
||||||
#define CPUARG "6502" //Target CPU Operand
|
#define CPUARG "6502" //Target CPU Operand
|
||||||
#define ORGOP "ORG" //Origin Pseudo-Op
|
#define ORGOP "ORG" //Origin Pseudo-Op
|
||||||
#define EQUOP "EQU" //Equate Pseudo-Op
|
#define EQUOP "EQU" //Equate Pseudo-Op
|
||||||
#define BYTEOP "BYTE" //Define Byte Pseudo-Op
|
#define BYTEOP "BYTE" //Define Byte Pseudo-Op
|
||||||
#define STROP "DS" //Define String Pseudo-Op
|
#define STROP "DS" //Define String Pseudo-Op
|
||||||
#define ALNOP "ALIGN" //Align Pseudo-Op
|
#define ALNOP "ALIGN" //Align Pseudo-Op
|
||||||
#define USEGOP "SEG.U" //Uninitalized Segment Pseudo-Op
|
#define USEGOP "SEG.U" //Uninitalized Segment Pseudo-Op
|
||||||
#define LOCOP "SUBROUTINE" //Local Variable Boundary Pseudo-Op
|
#define LOCOP "SUBROUTINE" //Local Variable Boundary Pseudo-Op
|
||||||
|
|
||||||
#define ASMFMT "%-7s %-3s %-12s %s\n" //Assembly Language Line printf Format
|
#define ASMFMT "%-7s %-3s %-12s %s\n" //Assembly Language Line printf Format
|
||||||
|
|
||||||
/* Internal defines */
|
/* Internal defines */
|
||||||
#define TRUE -1
|
#define TRUE -1
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
|
|
||||||
void initim(); //Initialize elapsed time counter
|
void prtpos(); //Print current file name and position
|
||||||
void prtpos(); //Print current file name and position
|
#define DEBUG(fmt, val) {if (debug) {prtpos(); printf(fmt, val);}}
|
||||||
void prttim(); //Print elapsed time
|
#define DETAIL(fmt, val) {if (debug) printf(fmt, val);}
|
||||||
#define DEBUG(fmt, val) {if (debug) {prtpos(); prttim(); printf(fmt, val);}}
|
#define ERROR(fmt, val, err) {fprintf(stderr, fmt, val);exterr(err);}
|
||||||
#define DETAIL(fmt, val) {if (debug) printf(fmt, val);}
|
|
||||||
#define ERROR(fmt, val, err) {fprintf(stderr, fmt, val);exterr(err);}
|
int debug; //Print Debug Info (TRUE or FALSE)
|
||||||
|
int cmos; //Flag: Use 65C02 Instruction Set
|
||||||
int debug; //Print Debug Info (TRUE or FALSE)
|
|
||||||
int cmos; //Flag: Use 65C02 Instruction Set
|
int gencmt; //Generate Assembly Language Comments
|
||||||
|
char asmcmt[LINELEN]; //Processed Assembly Language Comment
|
||||||
int gencmt; //Generate Assembly Language Comments
|
|
||||||
char asmcmt[LINELEN]; //Processed Assembly Language Comment
|
int curcol, curlin; //Position in Source Code
|
||||||
|
int savcol, savlin; //Save Position in Source Code
|
||||||
int curcol, curlin; //Position in Source Code
|
|
||||||
int savcol, savlin; //Save Position in Source Code
|
int bgntim; //Starting Time
|
||||||
|
|
||||||
int bgntim; //Starting Time
|
int nxtchr; //Next Character of Source File to Process
|
||||||
|
int nxtupc; //Next Character Converted to Uppercase
|
||||||
int nxtchr; //Next Character of Source File to Process
|
int savchr; //Holds nxtchr when switching input files
|
||||||
int nxtupc; //Next Character Converted to Uppercase
|
|
||||||
int savchr; //Holds nxtchr when switching input files
|
int wrdlen; //Length of Parsed Word
|
||||||
|
char word[LINELEN]; //Word parsed from source file
|
||||||
int wrdlen; //Length of Parsed Word
|
char uword[LINELEN]; //Word converted to uppercase
|
||||||
char word[LINELEN]; //Word parsed from source file
|
int pstlen; //Length of Parsed String
|
||||||
char uword[LINELEN]; //Word converted to uppercase
|
char pstrng[LINELEN]; //String parsed fron source file
|
||||||
int pstlen; //Length of Parsed String
|
char cmtasm[LINELEN]; //Assembly Language Comment Text
|
||||||
char pstrng[LINELEN]; //String parsed fron source file
|
char cputyp[LINELEN]; //CPU Type
|
||||||
char cmtasm[LINELEN]; //Assembly Language Comment Text
|
|
||||||
char cputyp[LINELEN]; //CPU Type
|
char hdrnam[FNAMLEN]; //Header File Name
|
||||||
|
char incdir[FNAMLEN]; //Include File Directory
|
||||||
char hdrnam[FNAMLEN]; //Header File Name
|
char inpnam[FNAMLEN]; //Input File Name
|
||||||
char incdir[FNAMLEN]; //Include File Directory
|
char subdir[SUBMAX][FNAMLEN]; //Include File SubDirectory
|
||||||
char inpnam[FNAMLEN]; //Input File Name
|
int subcnt; //Number of Include Directories
|
||||||
char subdir[SUBMAX][FNAMLEN]; //Include File SubDirectory
|
int subidx; //Index into subdir[]
|
||||||
int subcnt; //Number of Include Directories
|
|
||||||
int subidx; //Index into subdir[]
|
int alcvar; //Allocate Variables Flag
|
||||||
|
int inblck; //Multiline Block Flag
|
||||||
int alcvar; //Allocate Variables Flag
|
int infunc; //Inside Function Definition Flag
|
||||||
int inblck; //Multiline Block Flag
|
int lsrtrn; //Last Statement was a Return Flag
|
||||||
int infunc; //Inside Function Definition Flag
|
int fcase; //First Case Statement Flag
|
||||||
int lsrtrn; //Last Statement was a Return Flag
|
|
||||||
int fcase; //First Case Statement Flag
|
int padcnt; //Number of Padding Bytes at End of Program
|
||||||
|
|
||||||
int padcnt; //Number of Padding Bytes at End of Program
|
void exterr(int errnum); //Print current file name & position and exit
|
||||||
|
void expctd(char *expected); //Print Expected message and exit
|
||||||
void exterr(int errnum); //Print current file name & position and exit
|
|
||||||
void expctd(char *expected); //Print Expected message and exit
|
void addcmt(char *s); //Append string to comment
|
||||||
|
void chrcmt(char c); //Append character to comment
|
||||||
void addcmt(char *s); //Append string to comment
|
void setcmt(char *s); //Set comment to string
|
||||||
void chrcmt(char c); //Append character to comment
|
#define SCMNT(str) if (gencmt) {setcmt(str);}
|
||||||
void setcmt(char *s); //Set comment to string
|
#define ACMNT(str) if (gencmt) {addcmt(str);}
|
||||||
#define SCMNT(str) if (gencmt) {setcmt(str);}
|
#define CCMNT(chr) if (gencmt) {chrcmt(chr);}
|
||||||
#define ACMNT(str) if (gencmt) {addcmt(str);}
|
#define LCMNT(str) if (gencmt) {setcmt(str); cmtlin();}
|
||||||
#define CCMNT(chr) if (gencmt) {chrcmt(chr);}
|
|
||||||
#define LCMNT(str) if (gencmt) {setcmt(str); cmtlin();}
|
|
||||||
|
|
911
src/expr.c
911
src/expr.c
|
@ -1,454 +1,457 @@
|
||||||
/***********************************
|
/***********************************
|
||||||
* C02 Expression Parsing Routines *
|
* C02 Expression Parsing Routines *
|
||||||
***********************************/
|
***********************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "asm.h"
|
#include "asm.h"
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "vars.h"
|
#include "vars.h"
|
||||||
#include "label.h"
|
#include "label.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
|
|
||||||
/* Push Term and Operator onto Stack */
|
/* Push Term and Operator onto Stack */
|
||||||
void pshtrm(void) {
|
void pshtrm(void) {
|
||||||
if (trmidx >= MAXTRM) ERROR("Maximum Function Call/Array Index Depth Exceeded", 0, EXIT_FAILURE)
|
if (trmidx >= MAXTRM) ERROR("Maximum Function Call/Array Index Depth Exceeded", 0, EXIT_FAILURE)
|
||||||
oprstk[trmidx] = oper; //Put Current Operator on Stack
|
oprstk[trmidx] = oper; //Put Current Operator on Stack
|
||||||
strcpy(trmstk[trmidx], term); //Put Current Term on Stack
|
strcpy(trmstk[trmidx], term); //Put Current Term on Stack
|
||||||
trmidx++; //Increment Stack Pointer
|
trmidx++; //Increment Stack Pointer
|
||||||
DEBUG("expr.pshtrm: Pushed term %s ", term)
|
DEBUG("expr.pshtrm: Pushed term %s ", term)
|
||||||
DETAIL("and operator '%onto stack'\n", oper)
|
DETAIL("and operator '%onto stack'\n", oper)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pop Term and Operator off Stack */
|
/* Pop Term and Operator off Stack */
|
||||||
void poptrm(void) {
|
void poptrm(void) {
|
||||||
trmidx--; //Decrement Stack Pointer
|
trmidx--; //Decrement Stack Pointer
|
||||||
strcpy(term, trmstk[trmidx]); //Restore Current Term from Stack
|
strcpy(term, trmstk[trmidx]); //Restore Current Term from Stack
|
||||||
oper = oprstk[trmidx]; //Restore Current Operator from Stack
|
oper = oprstk[trmidx]; //Restore Current Operator from Stack
|
||||||
DEBUG("expr.pshtrm: Popped term %s ", term)
|
DEBUG("expr.pshtrm: Popped term %s ", term)
|
||||||
DETAIL("and operator '%c' off stack\n", oper)
|
DETAIL("and operator '%c' off stack\n", oper)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse value (literal or identifier) *
|
/* Parse value (literal or identifier) *
|
||||||
* Args: alwreg - allow registers *
|
* Args: alwreg - allow registers *
|
||||||
8 alwcon - allow constants *
|
8 alwcon - allow constants *
|
||||||
* Sets: value - the value (as a string) *
|
* Sets: value - the value (as a string) *
|
||||||
* valtyp - value type */
|
* valtyp - value type */
|
||||||
void prsval(int alwreg, int alwcon) {
|
void prsval(int alwreg, int alwcon) {
|
||||||
DEBUG("expr.prsval: Parsing value\n", 0)
|
DEBUG("expr.prsval: 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 if (isbtop()) prsbop(); //Parse Byte Operator
|
||||||
else expctd("literal or variable");
|
else expctd("literal or variable");
|
||||||
DEBUG("expr.prsval: Parsed value %s ", value)
|
DEBUG("expr.prsval: Parsed value %s ", value)
|
||||||
DETAIL("of type %d\n", valtyp)
|
DETAIL("of type %d\n", valtyp)
|
||||||
skpspc();
|
skpspc();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process Unary Minus */
|
/* Process Unary Minus */
|
||||||
void prcmns(void) {
|
void prcmns(void) {
|
||||||
DEBUG("Processing unary minus", 0)
|
DEBUG("Processing unary minus", 0)
|
||||||
asmlin("LDA", "#$00"); //Handle Unary Minus
|
asmlin("LDA", "#$00"); //Handle Unary Minus
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse array index *
|
/* Parse array index *
|
||||||
* Args: clbrkt - require closing bracket *
|
* Args: clbrkt - require closing bracket *
|
||||||
* Sets: value - array index or *
|
* Sets: value - array index or *
|
||||||
* "" if no index defined */
|
* "" if no index defined */
|
||||||
void prsidx(int clbrkt) {
|
void prsidx(int clbrkt) {
|
||||||
expect('[');
|
expect('[');
|
||||||
prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants
|
prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants
|
||||||
DEBUG("expr.prsidx: Parsed array index '%s'\n", value)
|
DEBUG("expr.prsidx: Parsed array index '%s'\n", value)
|
||||||
if (clbrkt) expect(']');
|
if (clbrkt) expect(']');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process Simple Array Index *
|
/* Process Simple Array Index *
|
||||||
* Uses: term - array variable name *
|
* Uses: term - array variable name *
|
||||||
* valtyp - array index value type *
|
* valtyp - array index value type *
|
||||||
* value - array index as string *
|
* value - array index as string *
|
||||||
* word - array index raw string *
|
* word - array index raw string *
|
||||||
* Sets: term - modified variable name */
|
* Sets: term - modified variable name */
|
||||||
void prcsix(void) {
|
void prcsix(void) {
|
||||||
DEBUG("expr.prcsix: Processing simple array index %s\n", word);
|
DEBUG("expr.prcsix: Processing simple array index %s\n", word);
|
||||||
if (valtyp == LITERAL) {
|
if (valtyp == LITERAL) {
|
||||||
strcat(term, "+");
|
strcat(term, "+");
|
||||||
strcat(term, word);
|
strcat(term, word);
|
||||||
}
|
}
|
||||||
else if (strcmp(value, "Y")==0)
|
else if (strcmp(value, "Y")==0)
|
||||||
strcat(term, ",Y");
|
strcat(term, ",Y");
|
||||||
else {
|
else {
|
||||||
if (strcmp(value, "A")==0) asmlin("TAX", "");
|
if (strcmp(value, "A")==0) asmlin("TAX", "");
|
||||||
else if (strcmp(value, "X")!=0) asmlin("LDX", value);
|
else if (strcmp(value, "X")!=0) asmlin("LDX", value);
|
||||||
strcat(term, ",X");
|
strcat(term, ",X");
|
||||||
}
|
}
|
||||||
DEBUG("expr.prcsix: Set term to %s\n", term);
|
DEBUG("expr.prcsix: Set term to %s\n", term);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process Expression Array Index */
|
/* Process Expression Array Index */
|
||||||
void prcxix(void) {
|
void prcxix(void) {
|
||||||
DEBUG("expr.prcxix: Processing Expression Array Index", 0)
|
DEBUG("expr.prcxix: Processing Expression Array Index", 0)
|
||||||
pshtrm(); //Push Array Variable onto Term Stack
|
pshtrm(); //Push Array Variable onto Term Stack
|
||||||
if (trmcnt) asmlin("PHA", ""); //Save Accumulator if not first term
|
if (trmcnt) asmlin("PHA", ""); //Save Accumulator if not first term
|
||||||
prcftm(FALSE); //Process First Term of Expression
|
prcftm(FALSE); //Process First Term of Expression
|
||||||
prsrxp(']'); //Parse Rest of Expression
|
prsrxp(']'); //Parse Rest of Expression
|
||||||
asmlin("TAX", ""); //Transfer Result of Expression to Index Register
|
asmlin("TAX", ""); //Transfer Result of Expression to Index Register
|
||||||
if (trmcnt) asmlin("PLA", ""); //Restore Accumator if not first term
|
if (trmcnt) asmlin("PLA", ""); //Restore Accumator if not first term
|
||||||
poptrm(); //Pop Array Variable off Term Stack
|
poptrm(); //Pop Array Variable off Term Stack
|
||||||
strcat(term, ",X");
|
strcat(term, ",X");
|
||||||
DEBUG("expr.prcxix: Set term to %s\n", term);
|
DEBUG("expr.prcxix: Set term to %s\n", term);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for, Parse, and Process Index */
|
/* Check for, Parse, and Process Index */
|
||||||
void chkidx(void) {
|
void chkidx(void) {
|
||||||
//DEBUG("Checking for Array Index with valtyp=%d\n", valtyp)
|
//DEBUG("Checking for Array Index with valtyp=%d\n", valtyp)
|
||||||
if (valtyp == ARRAY) {
|
if (valtyp == ARRAY) {
|
||||||
if (look('-')) {
|
if (look('-')) {
|
||||||
prcmns();
|
prcmns();
|
||||||
prcxix();
|
prcxix();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
prsidx(FALSE);
|
prsidx(FALSE);
|
||||||
if (valtyp > REGISTER) prcxix();
|
if (valtyp > REGISTER) prcxix();
|
||||||
else if (look(']')) prcsix();
|
else if (look(']')) prcsix();
|
||||||
else prcxix();
|
else prcxix();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse Pointer *
|
/* Parse Pointer *
|
||||||
* Sets: term - Compiled Pointer */
|
* Sets: term - Compiled Pointer */
|
||||||
void prsptr(void) {
|
void prsptr(void) {
|
||||||
DEBUG("Parsing pointer\n", 0)
|
DEBUG("Parsing pointer\n", 0)
|
||||||
expect('*'); //Pointer Dereference Operator
|
expect('*'); //Pointer Dereference Operator
|
||||||
prsvar(FALSE,FALSE); //Parse Variable to Dereference
|
prsvar(FALSE,FALSE); //Parse Variable to Dereference
|
||||||
strcpy(term, value);
|
strcpy(term, value);
|
||||||
if (varble.modifr != MTZP) ERROR("Illegal dereference of non-pointer variable %s.\n", value, EXIT_FAILURE)
|
if (varble.modifr != MTZP) ERROR("Illegal dereference of non-pointer variable %s.\n", value, EXIT_FAILURE)
|
||||||
DEBUG("expr.prsptr: Set term to %s\n", term);
|
DEBUG("expr.prsptr: Set term to %s\n", term);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process Pointer Index *
|
/* Process Pointer Index *
|
||||||
* Sets: term - Compiled Pointer */
|
* Sets: term - Compiled Pointer */
|
||||||
void prcptx(char *index) {
|
void prcptx(char *index) {
|
||||||
DEBUG("expr.prcptx: Processing Dereferenced Pointer %s ", term)
|
DEBUG("expr.prcptx: Processing Dereferenced Pointer %s ", term)
|
||||||
DETAIL("index [%s]\n", index)
|
DETAIL("index [%s]\n", index)
|
||||||
if (strcmp(index,"X")==0) ERROR("Illegal use of register X\n", 0, EXIT_FAILURE);
|
if (strcmp(index,"X")==0) ERROR("Illegal use of register X\n", 0, EXIT_FAILURE);
|
||||||
if (strcmp(index,"A")==0) asmlin("TAY", "");
|
if (strcmp(index,"A")==0) asmlin("TAY", "");
|
||||||
else if (strcmp(index,"Y") != 0) asmlin("LDY", index);
|
else if (strcmp(index,"Y") != 0) asmlin("LDY", index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process Pointer *
|
/* Process Pointer *
|
||||||
* Sets: term - Compiled Pointer */
|
* Sets: term - Compiled Pointer */
|
||||||
int prcptr(void) {
|
int prcptr(void) {
|
||||||
prsptr();
|
prsptr();
|
||||||
DEBUG("expr.prcptr: Dereferencing Pointer %s\n", value);
|
DEBUG("expr.prcptr: Dereferencing Pointer %s\n", value);
|
||||||
if (valtyp == ARRAY) {
|
if (valtyp == ARRAY) {
|
||||||
prsidx(TRUE);
|
prsidx(TRUE);
|
||||||
prcptx(value);
|
prcptx(value);
|
||||||
sprintf(word, "(%s),Y", term);
|
sprintf(word, "(%s),Y", term);
|
||||||
} else if (cmos) {
|
} else if (cmos) {
|
||||||
sprintf(word, "(%s)", term);
|
sprintf(word, "(%s)", term);
|
||||||
} else {
|
} else {
|
||||||
asmlin("LDY","0");
|
asmlin("LDY","0");
|
||||||
sprintf(word, "(%s),Y", term);
|
sprintf(word, "(%s),Y", term);
|
||||||
}
|
}
|
||||||
strcpy(term, word);
|
strcpy(term, word);
|
||||||
DEBUG("expr.prcptr: Set term to %s\n", term);
|
DEBUG("expr.prcptr: Set term to %s\n", term);
|
||||||
return FALSE; //Return Value Not an Integer
|
return FALSE; //Return Value Not an Integer
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse Term in Expression *
|
/* Parse Term in Expression *
|
||||||
* Sets: term - the term (as a string) *
|
* Sets: term - the term (as a string) *
|
||||||
* Returns: TRUE if term is an integer */
|
* Returns: TRUE if term is an integer */
|
||||||
int prstrm(int alwint) {
|
int prstrm(int alwint) {
|
||||||
DEBUG("Parsing term\n", 0)
|
DEBUG("Parsing term\n", 0)
|
||||||
if (match('*')) return prcptr(); //Parse and Deference Pointer
|
if (match('*')) return prcptr(); //Parse and Deference Pointer
|
||||||
prsval(FALSE, TRUE); //Parse Value - Disallow Registers, Allow Constants
|
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 && prcivr(alwint)) return TRUE;
|
if (valtyp == VARIABLE && prcivr(alwint)) return TRUE;
|
||||||
DEBUG("expr.prstrm: Parsed term %s\n", term)
|
DEBUG("expr.prstrm: Parsed term %s\n", term)
|
||||||
chkidx(); //Check for Array Index
|
chkidx(); //Check for Array Index
|
||||||
skpspc();
|
skpspc();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process Address Reference
|
/* Process Address Reference
|
||||||
* Args: adract = Address Action (adacts) *
|
* Args: adract = Address Action (adacts) *
|
||||||
* symbol = Symbol to Process */
|
* symbol = Symbol to Process */
|
||||||
void prcadr(int adract, char* symbol) {
|
void prcadr(int adract, char* symbol) {
|
||||||
DEBUG("Processing address '%s'\n", word)
|
DEBUG("Processing address '%s'\n", word)
|
||||||
strcpy(word,"#>(");
|
strcpy(word,"#>(");
|
||||||
strcat(word,symbol);
|
strcat(word,symbol);
|
||||||
strcat(word,")");
|
strcat(word,")");
|
||||||
if (adract == ADPUSH) { asmlin("LDA", word); asmlin("PHA", ""); }
|
if (adract == ADPUSH) { asmlin("LDA", word); asmlin("PHA", ""); }
|
||||||
else asmlin("LDY", word);
|
else asmlin("LDY", word);
|
||||||
strcpy(word,"#<(");
|
strcpy(word,"#<(");
|
||||||
strcat(word,symbol);
|
strcat(word,symbol);
|
||||||
strcat(word,")");
|
strcat(word,")");
|
||||||
if (adract == ADPUSH) { asmlin("LDA", word); asmlin("PHA", ""); }
|
if (adract == ADPUSH) { asmlin("LDA", word); asmlin("PHA", ""); }
|
||||||
else asmlin("LDX", word);
|
else asmlin("LDX", word);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse and Compile Address of Operator *
|
/* Parse and Compile Address of Operator *
|
||||||
* Args: adract = Address Action */
|
* Args: adract = Address Action */
|
||||||
void prsadr(int adract) {
|
void prsadr(int adract) {
|
||||||
DEBUG("Parsing address\n", 0)
|
DEBUG("expr.prsadr: Parsing address\n", 0)
|
||||||
if (isnpre()) prsnum(0xFFFF);
|
if (isnpre()) prsnum(0xFFFF);
|
||||||
else {
|
else {
|
||||||
getwrd();
|
getwrd();
|
||||||
if (fndlab(word)) strcpy(value, word);
|
if (fndlab(word)) strcpy(value, word);
|
||||||
else prsvrw(FALSE, TRUE);
|
else prsvrw(FALSE, TRUE);
|
||||||
}
|
}
|
||||||
if (adract) prcadr(adract, value); //Compile Address Reference
|
if (adract) prcadr(adract, value); //Compile Address Reference
|
||||||
else strcpy(word, value); //Save for Calling Routine
|
else strcpy(word, value); //Save for Calling Routine
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse and Create Anonymous String *
|
/* Parse and Create Anonymous String *
|
||||||
* Args: adract = Address Action *
|
* Args: adract = Address Action *
|
||||||
* alwstr = Allow String */
|
* alwstr = Allow String */
|
||||||
void prsstr(int adract, int alwstr) {
|
void prsstr(int adract, int alwstr) {
|
||||||
if (!alwstr) ERROR("Illegal String Reference", 0, EXIT_FAILURE)
|
if (!alwstr) ERROR("Illegal String Reference", 0, EXIT_FAILURE)
|
||||||
DEBUG("Parsing anonymous string\n", 0)
|
DEBUG("Parsing anonymous string\n", 0)
|
||||||
newlbl(vrname); //Generate Variable Name
|
newlbl(vrname); //Generate Variable Name
|
||||||
value[0] = 0; //Use Variable Size 0
|
value[0] = 0; //Use Variable Size 0
|
||||||
setvar(MTNONE, VTCHAR); //Set Variable Name, Type, and Size
|
setvar(MTNONE, VTCHAR); //Set Variable Name, Type, and Size
|
||||||
prsdts(); //Parse Data String
|
prsdts(); //Parse Data String
|
||||||
setdat(); //Set Variable Data
|
setdat(); //Set Variable Data
|
||||||
varcnt++; //Increment Variable Counter
|
varcnt++; //Increment Variable Counter
|
||||||
if (adract) prcadr(adract, vrname); //Compile Address Reference
|
if (adract) prcadr(adract, vrname); //Compile Address Reference
|
||||||
else strcpy(word, vrname); //Save for Calling Routine
|
else strcpy(word, vrname); //Save for Calling Routine
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for and Process Address or String *
|
/* Check for and Process Address or String *
|
||||||
* Args: adract = Address Action *
|
* Args: adract = Address Action *
|
||||||
* alwstr = Allow String */
|
* alwstr = Allow String */
|
||||||
int chkadr(int adract, int alwstr) {
|
int chkadr(int adract, int alwstr) {
|
||||||
DEBUG("Checking for Address or String\n", 0)
|
DEBUG("expr.chkadr: Checking for Address or String\n", 0)
|
||||||
int result = TRUE;
|
int result = TRUE;
|
||||||
if (look('&')) prsadr(adract);
|
if (look('&')) prsadr(adract);
|
||||||
else if (match('"')) prsstr(adract, alwstr);
|
else if (match('"')) prsstr(adract, alwstr);
|
||||||
else result = FALSE;
|
else result = FALSE;
|
||||||
skpspc();
|
skpspc();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse Byte Operator */
|
/* Parse Byte Operator */
|
||||||
void prsbop(void) {
|
void prsbop(void) {
|
||||||
char byteop = getnxt();
|
char byteop = getnxt();
|
||||||
CCMNT(byteop);
|
CCMNT(byteop);
|
||||||
DEBUG("Parsing byte operator '%c'\n", byteop)
|
DEBUG("Parsing byte operator '%c'\n", byteop)
|
||||||
if (chkadr(FALSE, FALSE)) {
|
if (chkadr(FALSE, FALSE)) {
|
||||||
sprintf(value, "%c(%s)", byteop, word);
|
sprintf(value, "%c(%s)", byteop, word);
|
||||||
valtyp = LITERAL;
|
valtyp = LITERAL;
|
||||||
} else {
|
} else {
|
||||||
reqvar(FALSE);
|
reqvar(FALSE);
|
||||||
if (vartyp != VTINT) ERROR("Integer Value Expected\n", 0, EXIT_FAILURE)
|
if (vartyp != VTINT) ERROR("Integer Value Expected\n", 0, EXIT_FAILURE)
|
||||||
if (byteop == '>') strcat(value, "+1");
|
if (byteop == '>') strcat(value, "+1");
|
||||||
vartyp = VTCHAR;
|
vartyp = VTCHAR;
|
||||||
}
|
}
|
||||||
DEBUG("Set value to \"%s\"\n", value)
|
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) {
|
||||||
int pusha = 0; int pushy = 0; //A and Y Arguments Pushed
|
int pusha = 0; int pushy = 0; //A and Y Arguments Pushed
|
||||||
if (!chkadr(ADLDYX, TRUE) && isxpre() || match('.')) {
|
DEBUG("expr.prsfpr: Parsing Function Argument or Return Values\n", 0)
|
||||||
if (look('.')) pusha = 255;
|
if (!chkadr(ADLDYX, TRUE) && isxpre() || match('.')) {
|
||||||
else {if (prsxpf(0)) goto prsfne;}
|
DEBUG("expr.prsfpr: Parsing Accumulator Expression\n", 0);
|
||||||
if (look(',') && !chkadr(ADLDYX, TRUE)) {
|
if (look('.')) pusha = 255;
|
||||||
if (look('.')) {
|
else {if (prsxpf(0)) goto prsfne;}
|
||||||
pushy = -1;
|
if (look(',') && !chkadr(ADLDYX, TRUE)) {
|
||||||
}
|
if (look('.')) {
|
||||||
else {
|
pushy = -1;
|
||||||
if (look('(')) {
|
}
|
||||||
if (pusha==0) {pusha = 1; asmlin("PHA","");} //Save A on Stack
|
else {
|
||||||
prsxpr(')'); asmlin("TAY", ""); //Evaluate Expression, and Copy to Y
|
if (look('(')) {
|
||||||
}
|
if (pusha==0) {pusha = 1; asmlin("PHA","");} //Save A on Stack
|
||||||
else {
|
prsxpr(')'); asmlin("TAY", ""); //Evaluate Expression, and Copy to Y
|
||||||
if (prstrm(TRUE)) goto prsfne;
|
}
|
||||||
asmlin("LDY", term);
|
else {
|
||||||
}
|
if (prstrm(TRUE)) goto prsfne;
|
||||||
}
|
asmlin("LDY", term);
|
||||||
if (look(',')) {
|
}
|
||||||
if (look('(')) {
|
}
|
||||||
if (pusha==0) {pusha = 1; asmlin("PHA","");} //Save A on Stack
|
if (look(',')) {
|
||||||
if (pushy==0) {pushy = 1; asmlin("PHA",""); asmlin("PHY","");} //Save Y on Stack
|
if (look('(')) {
|
||||||
prsxpr(')'); asmlin("TAX", ""); //Evaluate Expression, and Copy to X
|
if (pusha==0) {pusha = 1; asmlin("PHA","");} //Save A on Stack
|
||||||
}
|
if (pushy==0) {pushy = 1; asmlin("PHA",""); asmlin("PHY","");} //Save Y on Stack
|
||||||
else {
|
prsxpr(')'); asmlin("TAX", ""); //Evaluate Expression, and Copy to X
|
||||||
prsval(FALSE, TRUE); //Parse Value - Disallow Registers, Allow Constants
|
}
|
||||||
if (valtyp > VARIABLE) ERROR("Illegal Value Function Argument\n", 0, EXIT_FAILURE);
|
else {
|
||||||
if (valtyp == VARIABLE && vartyp != VTCHAR) ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE);
|
prsval(FALSE, TRUE); //Parse Value - Disallow Registers, Allow Constants
|
||||||
asmlin("LDX", value);
|
if (valtyp > VARIABLE) ERROR("Illegal Value Function Argument\n", 0, EXIT_FAILURE);
|
||||||
}
|
if (valtyp == VARIABLE && vartyp != VTCHAR) ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE);
|
||||||
}
|
asmlin("LDX", value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prsfne:
|
}
|
||||||
if (pushy==1) {asmlin("PLA",""); asmlin("TAY","");} //Pull Y Off Stack
|
}
|
||||||
if (pusha==1) asmlin("PLA",""); //Pull A Off Stack
|
prsfne:
|
||||||
expect(trmntr);
|
if (pushy==1) {asmlin("PLA",""); asmlin("TAY","");} //Pull Y Off Stack
|
||||||
}
|
if (pusha==1) asmlin("PLA",""); //Pull A Off Stack
|
||||||
|
expect(trmntr);
|
||||||
/* Parse function call */
|
}
|
||||||
void prsfnc(char trmntr) {
|
|
||||||
DEBUG("Processing Function Call '%s'\n", term)
|
/* Parse function call */
|
||||||
//int argexp = FALSE; //Expression(s) in second and third argument
|
void prsfnc(char trmntr) {
|
||||||
pshtrm(); //Push Function Name onto Term Stack
|
DEBUG("Processing Function Call '%s'\n", term)
|
||||||
skpchr(); //skip open paren
|
//int argexp = FALSE; //Expression(s) in second and third argument
|
||||||
CCMNT('(');
|
pshtrm(); //Push Function Name onto Term Stack
|
||||||
prsfpr(')'); //Parse Function Parameters
|
skpchr(); //skip open paren
|
||||||
expect(trmntr);
|
CCMNT('(');
|
||||||
poptrm(); //Pop Function Name off Term Stack
|
prsfpr(')'); //Parse Function Parameters
|
||||||
asmlin("JSR", term);
|
expect(trmntr);
|
||||||
skpspc();
|
poptrm(); //Pop Function Name off Term Stack
|
||||||
}
|
asmlin("JSR", term);
|
||||||
|
skpspc();
|
||||||
/* Process Integer Variable */
|
}
|
||||||
void prcvri(void) {
|
|
||||||
DEBUG("Processing Integer Variable '%s'\n", value)
|
/* Process Integer Variable */
|
||||||
asmlin("LDX", value);
|
void prcvri(void) {
|
||||||
strcat(value, "+1");
|
DEBUG("Processing Integer Variable '%s'\n", value)
|
||||||
asmlin("LDY", value);
|
asmlin("LDX", value);
|
||||||
}
|
strcat(value, "+1");
|
||||||
|
asmlin("LDY", value);
|
||||||
/* Process Integer Variable in Term *
|
}
|
||||||
* Args: alwint = Allow Integer-Like Variable *
|
|
||||||
* Returns: Integer-Like Variable Processed - TRUE/FALSE */
|
/* Process Integer Variable in Term *
|
||||||
int prcivr(int alwint) {
|
* Args: alwint = Allow Integer-Like Variable *
|
||||||
switch (vartyp) {
|
* Returns: Integer-Like Variable Processed - TRUE/FALSE */
|
||||||
case VTINT:
|
int prcivr(int alwint) {
|
||||||
if (!alwint) ERROR("Illegal Use of Integer Variable %s\n", word, EXIT_FAILURE)
|
switch (vartyp) {
|
||||||
prcvri();
|
case VTINT:
|
||||||
return TRUE;
|
if (!alwint) ERROR("Illegal Use of Integer Variable %s\n", word, EXIT_FAILURE)
|
||||||
case VTARRAY:
|
prcvri();
|
||||||
if (!alwint) ERROR("Illegal Reference to Array %s\n", word, EXIT_FAILURE)
|
return TRUE;
|
||||||
prcadr(ADNONE, term);
|
case VTARRAY:
|
||||||
return TRUE;
|
if (!alwint) ERROR("Illegal Reference to Array %s\n", word, EXIT_FAILURE)
|
||||||
case VTSTRUCT:
|
prcadr(ADNONE, term);
|
||||||
if (!alwint) ERROR("Illegal Reference to Struct %s\n", word, EXIT_FAILURE)
|
return TRUE;
|
||||||
prcadr(ADNONE, term);
|
case VTSTRUCT:
|
||||||
return TRUE;
|
if (!alwint) ERROR("Illegal Reference to Struct %s\n", word, EXIT_FAILURE)
|
||||||
default:
|
prcadr(ADNONE, term);
|
||||||
return FALSE;
|
return TRUE;
|
||||||
}
|
default:
|
||||||
}
|
return FALSE;
|
||||||
|
}
|
||||||
/* Process first term of expression */
|
}
|
||||||
int prcftm(int alwint) {
|
|
||||||
DEBUG("Processing first term '%s'\n", value)
|
/* Process first term of expression */
|
||||||
strcpy(term, value);
|
int prcftm(int alwint) {
|
||||||
if (valtyp == VARIABLE && prcivr(alwint)) return TRUE;
|
DEBUG("Processing first term '%s'\n", value)
|
||||||
if (valtyp == FUNCTION) prsfnc(0); //Parse Expression Function
|
strcpy(term, value);
|
||||||
else if (wordis("A")) return FALSE;
|
if (valtyp == VARIABLE && prcivr(alwint)) return TRUE;
|
||||||
else if (wordis("X")) asmlin("TXA", "");
|
if (valtyp == FUNCTION) prsfnc(0); //Parse Expression Function
|
||||||
else if (wordis("Y")) asmlin("TYA", "");
|
else if (wordis("A")) return FALSE;
|
||||||
else { chkidx(); asmlin("LDA", term); }
|
else if (wordis("X")) asmlin("TXA", "");
|
||||||
return FALSE;
|
else if (wordis("Y")) asmlin("TYA", "");
|
||||||
}
|
else { chkidx(); asmlin("LDA", term); }
|
||||||
|
return FALSE;
|
||||||
/* Parse first term of expession *
|
}
|
||||||
* First term can include function calls */
|
|
||||||
int prsftm(int alwint) {
|
/* Parse first term of expession *
|
||||||
DEBUG("Parsing first term\n", 0)
|
* First term can include function calls */
|
||||||
if (match('*')) {
|
int prsftm(int alwint) {
|
||||||
prcptr(); //Parse and Deference Pointer
|
DEBUG("Parsing first term\n", 0)
|
||||||
asmlin("LDA", term);
|
if (match('*')) {
|
||||||
return FALSE;
|
prcptr(); //Parse and Deference Pointer
|
||||||
}
|
asmlin("LDA", term);
|
||||||
prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants
|
return FALSE;
|
||||||
return prcftm(alwint);
|
}
|
||||||
}
|
prsval(TRUE, TRUE); //Parse Value, Allow Registers & Constants
|
||||||
|
return prcftm(alwint);
|
||||||
/* Process Arithmetic or Bitwise Operator *
|
}
|
||||||
* and the term that follows it */
|
|
||||||
void prcopr(void) {
|
/* Process Arithmetic or Bitwise Operator *
|
||||||
DEBUG("Processing operator '%c'\n", oper)
|
* and the term that follows it */
|
||||||
switch(oper) {
|
void prcopr(void) {
|
||||||
case '+': asmlin("CLC", ""); asmlin("ADC", term); break; //Addition
|
DEBUG("Processing operator '%c'\n", oper)
|
||||||
case '-': asmlin("SEC", ""); asmlin("SBC", term); break; //Subtraction
|
switch(oper) {
|
||||||
case '&': asmlin("AND", term); break; //Bitwise AND
|
case '+': asmlin("CLC", ""); asmlin("ADC", term); break; //Addition
|
||||||
case '!': //For systems that don't have pipe in character set
|
case '-': asmlin("SEC", ""); asmlin("SBC", term); break; //Subtraction
|
||||||
case '|': asmlin("ORA", term); break; //Bitwise OR
|
case '&': asmlin("AND", term); break; //Bitwise AND
|
||||||
case '^': asmlin("EOR", term); break; //Bitwise XOR
|
case '!': //For systems that don't have pipe in character set
|
||||||
default: ERROR("Unrecognized operator '%c'\n", oper, EXIT_FAILURE)
|
case '|': asmlin("ORA", term); break; //Bitwise OR
|
||||||
}
|
case '^': asmlin("EOR", term); break; //Bitwise XOR
|
||||||
oper = 0;
|
default: ERROR("Unrecognized operator '%c'\n", oper, EXIT_FAILURE)
|
||||||
}
|
}
|
||||||
|
oper = 0;
|
||||||
/* Parse Remainder of Expression */
|
}
|
||||||
void prsrxp(char trmntr) {
|
|
||||||
skpspc();
|
/* Parse Remainder of Expression */
|
||||||
while (isoper()) {
|
void prsrxp(char trmntr) {
|
||||||
trmcnt++; //Increment Expression Depth
|
skpspc();
|
||||||
prsopr(); //Parse Operator
|
while (isoper()) {
|
||||||
prstrm(FALSE); //Parse Term
|
trmcnt++; //Increment Expression Depth
|
||||||
prcopr(); //Process Operator
|
prsopr(); //Parse Operator
|
||||||
trmcnt--; //Decrement Expression Depth
|
prstrm(FALSE); //Parse Term
|
||||||
}
|
prcopr(); //Process Operator
|
||||||
expect(trmntr);
|
trmcnt--; //Decrement Expression Depth
|
||||||
}
|
}
|
||||||
|
expect(trmntr);
|
||||||
int prsxpp(char trmntr, int alwint) {
|
}
|
||||||
DEBUG("Parsing expression\n", 0)
|
|
||||||
skpspc();
|
int prsxpp(char trmntr, int alwint) {
|
||||||
trmcnt = 0; //Initialize Expression Depth
|
DEBUG("Parsing expression\n", 0)
|
||||||
if (match('-')) prcmns(); //Process Unary Minus
|
skpspc();
|
||||||
else if (prsftm(alwint)) return TRUE; //Parse First Term
|
trmcnt = 0; //Initialize Expression Depth
|
||||||
prsrxp(trmntr); //Parse Remainder of Express
|
if (match('-')) prcmns(); //Process Unary Minus
|
||||||
return FALSE;
|
else if (prsftm(alwint)) return TRUE; //Parse First Term
|
||||||
}
|
prsrxp(trmntr); //Parse Remainder of Express
|
||||||
|
return FALSE;
|
||||||
/* Parse and compile expression */
|
}
|
||||||
void prsxpr(char trmntr) {
|
|
||||||
prsxpp(trmntr, FALSE);
|
/* Parse and compile expression */
|
||||||
}
|
void prsxpr(char trmntr) {
|
||||||
|
prsxpp(trmntr, FALSE);
|
||||||
/* Parse and compile function parameter expression *
|
}
|
||||||
* Returns: TRUE if Integer Expression */
|
|
||||||
int prsxpf(char trmntr) {
|
/* Parse and compile function parameter expression *
|
||||||
return prsxpp(trmntr, TRUE);
|
* Returns: TRUE if Integer Expression */
|
||||||
}
|
int prsxpf(char trmntr) {
|
||||||
|
DEBUG("expr.prsxpf: Parsing Function Expression\n", 0)
|
||||||
/* Parse and Compile Integer Expression *
|
return prsxpp(trmntr, TRUE);
|
||||||
* (Address, Integer Literal, Variable, *
|
}
|
||||||
* Struct Member, or Function) *
|
|
||||||
* Args: trmntr - expression terminator *
|
/* Parse and Compile Integer Expression *
|
||||||
* asmxpr - assemble expression *
|
* (Address, Integer Literal, Variable, *
|
||||||
* Sets: value - Parsed Value or Symbol */
|
* Struct Member, or Function) *
|
||||||
void prsxpi(char trmntr, int asmxpr) {
|
* Args: trmntr - expression terminator *
|
||||||
skpspc();
|
* asmxpr - assemble expression *
|
||||||
DEBUG("Parsing integer expression\n", 0)
|
* Sets: value - Parsed Value or Symbol */
|
||||||
if (!chkadr(TRUE, FALSE)) {
|
void prsxpi(char trmntr, int asmxpr) {
|
||||||
if (isnpre()) {
|
skpspc();
|
||||||
DEBUG("Parsing Integer Literal\n", 0)
|
DEBUG("Parsing integer expression\n", 0)
|
||||||
int number = prsnum(0xFFFF); //Parse Number into value
|
if (!chkadr(TRUE, FALSE)) {
|
||||||
if (asmxpr) {
|
if (isnpre()) {
|
||||||
sprintf(value, "#%d", number & 0xFF); asmlin("LDX", value);
|
DEBUG("Parsing Integer Literal\n", 0)
|
||||||
sprintf(value, "#%d", number >> 8); asmlin("LDY", value);
|
int number = prsnum(0xFFFF); //Parse Number into value
|
||||||
}
|
if (asmxpr) {
|
||||||
} else if (isalph()) {
|
sprintf(value, "#%d", number & 0xFF); asmlin("LDX", value);
|
||||||
prsvar(FALSE, TRUE);
|
sprintf(value, "#%d", number >> 8); asmlin("LDY", value);
|
||||||
if (valtyp == FUNCTION) {
|
}
|
||||||
strcpy(term, value);
|
} else if (isalph()) {
|
||||||
DEBUG("expr.prsxpi: Set term to %s\n", term)
|
prsvar(FALSE, TRUE);
|
||||||
prsfnc(0); //Parse Expression Function
|
if (valtyp == FUNCTION) {
|
||||||
} else if (valtyp == STRUCTURE) {
|
strcpy(term, value);
|
||||||
prsmbr(value);
|
DEBUG("expr.prsxpi: Set term to %s\n", term)
|
||||||
if (vartyp != VTINT) ERROR("Illegal Member %s In Integer Expression", value, EXIT_FAILURE)
|
prsfnc(0); //Parse Expression Function
|
||||||
} else if (valtyp == VARIABLE && vartyp == VTINT) {
|
} else if (valtyp == STRUCTURE) {
|
||||||
if (asmxpr) prcvri(); //Process Integer Variable
|
prsmbr(value);
|
||||||
} else {
|
if (vartyp != VTINT) ERROR("Illegal Member %s In Integer Expression", value, EXIT_FAILURE)
|
||||||
ERROR("Illegal Variable %s In Integer Expression", value, EXIT_FAILURE)
|
} else if (valtyp == VARIABLE && vartyp == VTINT) {
|
||||||
}
|
if (asmxpr) prcvri(); //Process Integer Variable
|
||||||
} else {
|
} else {
|
||||||
ERROR("Expected Integer Value or Function\n", 0, EXIT_FAILURE);
|
ERROR("Illegal Variable %s In Integer Expression", value, EXIT_FAILURE)
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
expect(trmntr);
|
ERROR("Expected Integer Value or Function\n", 0, EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
expect(trmntr);
|
||||||
|
}
|
||||||
|
|
|
@ -177,7 +177,7 @@ void pincdr(void) {
|
||||||
void phdwrd(void) {
|
void phdwrd(void) {
|
||||||
getwrd();
|
getwrd();
|
||||||
if (match(':')) prslab();
|
if (match(':')) prslab();
|
||||||
else if (!ptype(MTNONE))
|
else if (!pmodfr() && !ptype(MTNONE))
|
||||||
ERROR("Unexpected word '%s' in header\n", word, EXIT_FAILURE)
|
ERROR("Unexpected word '%s' in header\n", word, EXIT_FAILURE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
src/vars.c
10
src/vars.c
|
@ -270,10 +270,12 @@ void addvar(int m, int t) {
|
||||||
if (fndvar(vrname)) ERROR("Duplicate declaration of variable '%s\n", vrname, EXIT_FAILURE)
|
if (fndvar(vrname)) ERROR("Duplicate declaration of variable '%s\n", vrname, EXIT_FAILURE)
|
||||||
if (t == VTVOID) ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE)
|
if (t == VTVOID) ERROR("Illegal Variable Type\n", 0, EXIT_FAILURE)
|
||||||
if (m & MTZP) {
|
if (m & MTZP) {
|
||||||
setlbl(vrname);
|
if (alcvar) {
|
||||||
sprintf(word, "$%hhX", zpaddr++);
|
setlbl(vrname);
|
||||||
if (t == VTINT) zpaddr++; //int uses two bytes
|
sprintf(word, "$%hhX", zpaddr++);
|
||||||
asmlin(EQUOP, word);
|
if (t == VTINT) zpaddr++; //int uses two bytes
|
||||||
|
asmlin(EQUOP, word);
|
||||||
|
}
|
||||||
strcpy(value, "*"); //Set Variable to Non Allocated
|
strcpy(value, "*"); //Set Variable to Non Allocated
|
||||||
}
|
}
|
||||||
else if (m & MTALS) {
|
else if (m & MTALS) {
|
||||||
|
|
27
test/README.md
Normal file
27
test/README.md
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
C02 Test Directory Contents
|
||||||
|
===========================
|
||||||
|
|
||||||
|
Compile and Run Batch Files
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
| c02.bat | Compile .c02 file into .asm file |
|
||||||
|
| a02.bat | Assemble .asm file into .bin file |
|
||||||
|
| a1.bat | Compile/Assemble .c02 file to .asc Monitor Format |
|
||||||
|
| a2.bat | Compile/Assemble .c02 file to .dsk and run AppleWin |
|
||||||
|
| c64.bat | Compile/Assemble .c02 file to .prg and run x64 |
|
||||||
|
| o1.bat | Compile/Assemble .c02 file to .tap for Oricutron |
|
||||||
|
| orao.bat | Compile/Assemble .c02 file to .wav for Orao Emulator |
|
||||||
|
| p65.bat | Compile/Assemble .c02 file to .bin for py65m |
|
||||||
|
| v8k.bat | Compile/Assemble .c02 file to .prg and run xvic |
|
||||||
|
| x16.bat | Compile/Assemble .c02 file to .prg and run x16emu |
|
||||||
|
|
||||||
|
C02 Test/Demo Programs
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
| hello.c02 | Print "HELLO WORLD" using prtstr() |
|
||||||
|
| echo.c02 | Echo typed characters to screen |
|
||||||
|
| echohex.c02 | Display Hex Codes for types characters |
|
||||||
|
| conds.c02 | Test Conditional operators |
|
||||||
|
| loops.c02 | Test Loop and Conditional keywords |
|
||||||
|
| scrntst.c02 | Test module screen.h02 functions |
|
||||||
|
| sdeftest.c02 | Test module stddef.h02 functions |
|
14
test/a02.bat
Normal file
14
test/a02.bat
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
@ECHO OFF
|
||||||
|
IF "%1" == "" (
|
||||||
|
ECHO Usage: %0 a02file
|
||||||
|
GOTO :EXIT
|
||||||
|
)
|
||||||
|
SET ASMEXT=""
|
||||||
|
IF EXIST %1.a02 SET ASMEXT=a02
|
||||||
|
IF EXIST %1.asm SET ASMEXT=asm
|
||||||
|
IF "%ASMEXT%" == "" (
|
||||||
|
ECHO Assembly File %1 Not Found
|
||||||
|
GOTO :EXIT
|
||||||
|
)
|
||||||
|
ECHO Assembling File %1.%ASMEXT%
|
||||||
|
..\a02.exe %1.%ASMEXT% %1.bin %1.lst >%1.out
|
|
@ -10,7 +10,7 @@ ECHO Compiling File %1.c02
|
||||||
IF ERRORLEVEL 1 EXIT /B
|
IF ERRORLEVEL 1 EXIT /B
|
||||||
|
|
||||||
ECHO Assembling File %1.asm
|
ECHO Assembling File %1.asm
|
||||||
dasm %1.asm -f1 -o%1.obj -l%1.lst -s%1.sym
|
..\a02 -p %1.asm %1.obj %1.lst
|
||||||
IF ERRORLEVEL 1 EXIT /B
|
IF ERRORLEVEL 1 EXIT /B
|
||||||
|
|
||||||
ECHO Converting Object File
|
ECHO Converting Object File
|
||||||
|
|
|
@ -9,7 +9,7 @@ ECHO Compiling File %1.c02
|
||||||
IF ERRORLEVEL 1 EXIT /B
|
IF ERRORLEVEL 1 EXIT /B
|
||||||
|
|
||||||
ECHO Assembling File %1.asm
|
ECHO Assembling File %1.asm
|
||||||
dasm %1.asm -f3 -o%1.obj -l%1.lst -s%1.sym
|
..\a02 %1.asm %1.obj %1.lst
|
||||||
IF ERRORLEVEL 1 EXIT /B
|
IF ERRORLEVEL 1 EXIT /B
|
||||||
|
|
||||||
ECHO Building Disk Image
|
ECHO Building Disk Image
|
||||||
|
|
10
test/c02.bat
Normal file
10
test/c02.bat
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
@ECHO OFF
|
||||||
|
IF EXIST %1.c02 GOTO COMPILE
|
||||||
|
ECHO File %1.c02 not found
|
||||||
|
GOTO EOF
|
||||||
|
|
||||||
|
:COMPILE
|
||||||
|
ECHO Compiling File %1.c02
|
||||||
|
..\c02.exe -h header %1 >%1.dbg
|
||||||
|
|
||||||
|
:EOF
|
14
test/c64.bat
14
test/c64.bat
|
@ -1,18 +1,20 @@
|
||||||
|
@REM Compile and Run C02 Program for C64
|
||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
|
|
||||||
IF EXIST %1.c02 GOTO COMPILE
|
IF EXIST %1.c02 GOTO COMPILE
|
||||||
ECHO File %1.c02 not found
|
ECHO File %1.c02 not found
|
||||||
GOTO EOF
|
GOTO EOF
|
||||||
|
|
||||||
:COMPILE
|
:COMPILE
|
||||||
ECHO Compiling File %1.c02 for Commodore 64
|
ECHO Compiling File %1.c02 for Commodore 64
|
||||||
..\c02.exe -h c64 -s c64 -s cbm %1 >%1.dbg
|
..\c02.exe -d -h c64 -s c64 -s cbm %1 >%1.dbg
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO EOF
|
IF %ERRORLEVEL% NEQ 0 GOTO EOF
|
||||||
ECHO Assembling File %1.asm
|
|
||||||
C:\Programs\dasm %1.asm -f1 -o%1.prg -l%1.lst -s%1.sym
|
|
||||||
|
|
||||||
|
ECHO Assembling File %1.asm
|
||||||
|
..\a02.exe -p %1.asm %1.prg %1.lst >%1.out
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO EOF
|
IF %ERRORLEVEL% NEQ 0 GOTO EOF
|
||||||
|
|
||||||
ECHO Starting Emulator
|
ECHO Starting Emulator
|
||||||
@start C:\Programs\WinVICE\x64.exe -config x64.ini %1.prg
|
start C:\Programs\WinVICE\x64.exe -config x64.ini %1.prg
|
||||||
|
|
||||||
:EOF
|
:EOF
|
||||||
|
|
104
test/conds.c02
104
test/conds.c02
|
@ -3,65 +3,57 @@
|
||||||
****************************************/
|
****************************************/
|
||||||
|
|
||||||
//Specify System Header using -H option
|
//Specify System Header using -H option
|
||||||
#include <stddef.h02>
|
|
||||||
#include <stdlib.h02>
|
|
||||||
#include <stdio.h02>
|
|
||||||
|
|
||||||
char allok;
|
char allok;
|
||||||
|
|
||||||
|
void passed() {putstr(" PASS");}
|
||||||
|
void passln() {passed(); newlin();}
|
||||||
|
void failed() {putstr(" FAIL"); allok = $00;}
|
||||||
|
void failln() {failed(); newlin();}
|
||||||
|
|
||||||
main:
|
main:
|
||||||
|
|
||||||
allok = #TRUE;
|
allok = $FF; //TRUE
|
||||||
|
|
||||||
|
putstr("TEST CONDITIONALS"); newlin();
|
||||||
|
|
||||||
|
putstr(" 1<>1"); if (1<>1) failed(); else passed();
|
||||||
|
putstr(" 1<>2"); if (1<>2) passln(); else failln();
|
||||||
|
putstr(" 1==1"); if (1==1) passed(); else failed();
|
||||||
|
putstr(" 1==2"); if (1==2) failln(); else passln();
|
||||||
|
putstr("1+1=2"); if (1+1 == 2) passed(); else failed();
|
||||||
|
putstr(" 2<1"); if (2<1) failln(); else passln();
|
||||||
|
putstr(" 1<1"); if (1<1) failed(); else passed();
|
||||||
|
putstr(" 1<2"); if (1<2) passln(); else failln();
|
||||||
|
|
||||||
|
putstr(" 1<=1"); if (1<=1) passed(); else failed();
|
||||||
|
putstr(" 1<=2"); if (1<=2) passln(); else failln();
|
||||||
|
putstr(" 2<=1"); if (2<=1) failed(); else passed();
|
||||||
|
putstr(" 2>1"); if (2>1) passln(); else failln();
|
||||||
|
putstr(" 1>1"); if (1>1) failed(); else passed();
|
||||||
|
putstr(" 1>2"); if (1>2) failln(); else passln();
|
||||||
|
putstr(" 1>=1"); if (1>=1) passed(); else failed();
|
||||||
|
putstr(" 1>=2"); if (1>=2) failln(); else passln();
|
||||||
|
putstr(" 2>=1"); if (2>=1) passed(); else failed();
|
||||||
|
putstr(" !0:+"); if (!0:+) failln(); else passln();
|
||||||
|
|
||||||
|
putstr("$FF:+"); if ($FF:+) failed(); else passed();
|
||||||
|
putstr(" $FF"); if ($FF) passln(); else failln();
|
||||||
|
putstr("$FF:-"); if ($FF:-) passed(); else failed();
|
||||||
|
putstr(" !$FF"); if (!$FF) failln(); else passln();
|
||||||
|
putstr("$00:+"); if ($00:+) passed(); else failed();
|
||||||
|
putstr(" $00"); if ($00) failln(); else passln();
|
||||||
|
putstr("$00:-"); if ($00:-) failed(); else passed();
|
||||||
|
putstr(" !$00"); if (!$00) passln(); else failln();
|
||||||
|
|
||||||
|
putstr(" 1!0"); if (1|0) passed(); else failed();
|
||||||
|
putstr(" !1!0"); if (!1|0) failln(); else passln();
|
||||||
|
putstr(" 1&0"); if (1&0) failed(); else passed();
|
||||||
|
putstr(" !1&0"); if (!1&0) passln(); else failln();
|
||||||
|
putstr(" 1^1"); if (1^1) failed(); else passed();
|
||||||
|
putstr(" !1^1"); if (!1^1) passln(); else failln();
|
||||||
|
|
||||||
|
if (allok) putstr("ALL TESTS PASSED"); newlin();
|
||||||
|
getchr();
|
||||||
|
goto exit;
|
||||||
|
|
||||||
putln("Test Conditionals");
|
|
||||||
|
|
||||||
puts(" 1<>1"); if (1<>1) failed(); else passed();
|
|
||||||
puts(" 1<>2"); if (1<>2) passln(); else failln();
|
|
||||||
puts(" 1==1"); if (1==1) passed(); else failed();
|
|
||||||
puts(" 1==2"); if (1==2) failln(); else passln();
|
|
||||||
puts("1+1=2"); if (1+1 == 2) passed(); else failed();
|
|
||||||
puts(" 2<1"); if (2<1) failln(); else passln();
|
|
||||||
puts(" 1<1"); if (1<1) failed(); else passed();
|
|
||||||
puts(" 1<2"); if (1<2) passln(); else failln();
|
|
||||||
|
|
||||||
puts(" 1<=1"); if (1<=1) passed(); else failed();
|
|
||||||
puts(" 1<=2"); if (1<=2) passln(); else failln();
|
|
||||||
puts(" 2<=1"); if (2<=1) failed(); else passed();
|
|
||||||
puts(" 2>1"); if (2>1) passln(); else failln();
|
|
||||||
puts(" 1>1"); if (1>1) failed(); else passed();
|
|
||||||
puts(" 1>2"); if (1>2) failln(); else passln();
|
|
||||||
puts(" 1>=1"); if (1>=1) passed(); else failed();
|
|
||||||
puts(" 1>=2"); if (1>=2) failln(); else passln();
|
|
||||||
puts(" 2>=1"); if (2>=1) passed(); else failed();
|
|
||||||
puts(" !0:+"); if (!0:+) failln(); else passln();
|
|
||||||
|
|
||||||
puts("$FF:+"); if ($FF:+) failed(); else passed();
|
|
||||||
puts(" $FF"); if ($FF) passln(); else failln();
|
|
||||||
puts("$FF:-"); if ($FF:-) passed(); else failed();
|
|
||||||
puts(" !$FF"); if (!$FF) failln(); else passln();
|
|
||||||
puts("$00:+"); if ($00:+) passed(); else failed();
|
|
||||||
puts(" $00"); if ($00) failln(); else passln();
|
|
||||||
puts("$00:-"); if ($00:-) failed(); else passed();
|
|
||||||
puts(" !$00"); if (!$00) passln(); else failln();
|
|
||||||
|
|
||||||
puts(" 1!0"); if (1|0) passed(); else failed();
|
|
||||||
puts(" !1!0"); if (!1|0) failln(); else passln();
|
|
||||||
puts(" 1&0"); if (1&0) failed(); else passed();
|
|
||||||
puts(" !1&0"); if (!1&0) passln(); else failln();
|
|
||||||
puts(" 1^1"); if (1^1) failed(); else passed();
|
|
||||||
puts(" !1^1"); if (!1^1) passln(); else failln();
|
|
||||||
|
|
||||||
puts(" atoc(\"0\")"); if (atoc("0")) failln(); else passln();
|
|
||||||
puts(" atoc(\"1\")"); if (atoc("1")) passln(); else failln();
|
|
||||||
puts(" atoc(\"127\"):+"); if (atoc("127"):+) passln(); else failln();
|
|
||||||
puts(" atoc(\"128\"):-"); if (atoc("128"):-) passln(); else failln();
|
|
||||||
|
|
||||||
if (allok) putln("All Tests Passed");
|
|
||||||
getc();
|
|
||||||
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
void passed() {puts(" Pass");}
|
|
||||||
void passln() {passed(); newlin();}
|
|
||||||
void failed() {puts(" Fail"); allok = #FALSE;}
|
|
||||||
void failln() {failed(); newlin();}
|
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
char key; //Key value
|
char key; //Key value
|
||||||
|
|
||||||
main:
|
main:
|
||||||
|
putstr("TYPE KEYS TO ECHO"); newlin();
|
||||||
|
putstr("ESCAPE/STOP TO END"); newlin();
|
||||||
while() {
|
while() {
|
||||||
key = getchr();
|
key = getchr();
|
||||||
select (key) {
|
select (key) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*******************************************************
|
/*******************************************************
|
||||||
* ECHOHEX - Test/Demo program for C02 Standard Header *
|
* ECHOHEX - Test/Demo program for C02 Standard Header *
|
||||||
* Displays ASCII Code of Typed Keys to Screen *
|
* Displays ASCII Code of Typed Keys to Screen *
|
||||||
|
* RETURN/ENTER moves to new line *
|
||||||
* ESCAPE/STOP key Ends Program *
|
* ESCAPE/STOP key Ends Program *
|
||||||
*******************************************************/
|
*******************************************************/
|
||||||
|
|
||||||
|
@ -9,9 +10,12 @@
|
||||||
char key; //Key value
|
char key; //Key value
|
||||||
|
|
||||||
main:
|
main:
|
||||||
|
putstr("PRESS KEYS TO DISPLAY"); newlin();
|
||||||
|
putstr("ESCAPE/STOP TO END"); newlin();
|
||||||
while() {
|
while() {
|
||||||
key = getchr();
|
key = getchr();
|
||||||
prbyte(key);
|
prbyte(key);
|
||||||
putchr(' ');
|
putchr(' ');
|
||||||
|
if (key==#RTNKEY) newlin();
|
||||||
if (key==#ESCKEY) goto exit;
|
if (key==#ESCKEY) goto exit;
|
||||||
}
|
}
|
||||||
|
|
12
test/hello.c02
Normal file
12
test/hello.c02
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/*****************************************************
|
||||||
|
* HELLO - Test/Demo program for C02 Standard Header *
|
||||||
|
* Prints "HELLO WORLD" and exits *
|
||||||
|
*****************************************************/
|
||||||
|
|
||||||
|
//Specify System Header using -H option
|
||||||
|
|
||||||
|
main:
|
||||||
|
putstr("HELLO WORLD");
|
||||||
|
newlin();
|
||||||
|
goto exit;
|
||||||
|
|
87
test/ints.c02
Normal file
87
test/ints.c02
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/****************************************************
|
||||||
|
* INTS - Test Integer Variables and Function Calls */
|
||||||
|
|
||||||
|
//Specify System Header using -H option
|
||||||
|
#include <screen.h02>
|
||||||
|
#include <stddef.h02>
|
||||||
|
#include <stdlib.h02>
|
||||||
|
#include <intlib.h02>
|
||||||
|
#include <stdio.h02>
|
||||||
|
#include <stdiox.h02>
|
||||||
|
#include <string.h02>
|
||||||
|
#include <test.h02>
|
||||||
|
|
||||||
|
char n; //Number of Characters
|
||||||
|
char r[255]; //Test Array
|
||||||
|
char s[128]; //Test String
|
||||||
|
const char istr = "9876";
|
||||||
|
const char t = "CONST STRING.";
|
||||||
|
|
||||||
|
alias int nmi = $FFFA; //NMI Vector
|
||||||
|
alias int rst = $FFFC; //Reset Vector
|
||||||
|
alias int brk = $FFFE; //Break Vector
|
||||||
|
|
||||||
|
int addr; //Various Addresses
|
||||||
|
int eoj; //End of Job
|
||||||
|
|
||||||
|
const int less = $789A;
|
||||||
|
const int more = $BCDE;
|
||||||
|
|
||||||
|
int yx, dd; //Function Arguments and Variables
|
||||||
|
char aa, xx, yy;
|
||||||
|
|
||||||
|
struct record {char name[8], index; int addr;};
|
||||||
|
struct record rec;
|
||||||
|
|
||||||
|
main:
|
||||||
|
|
||||||
|
eoj = getend();
|
||||||
|
|
||||||
|
setdst(&rec.name); strcpy("FRED");
|
||||||
|
rec.index = $AB;
|
||||||
|
rec.addr = $CDEF;
|
||||||
|
|
||||||
|
newlin();
|
||||||
|
|
||||||
|
/* Print Vector Contents */
|
||||||
|
setdst(nmi); printf("NMI=$%w%n");
|
||||||
|
setdst(rst); printf("RST=$%w%n");
|
||||||
|
setdst(brk); printf("BRK=$%w%n%n");
|
||||||
|
|
||||||
|
/* Print Contents of EOJ */
|
||||||
|
setdst(eoj); printf("EOJ=$%w%n%n");
|
||||||
|
|
||||||
|
anykey();
|
||||||
|
|
||||||
|
/* Test Function Call Arguments */
|
||||||
|
putln("ADDR=49152"); addr = 49152; setdst(&49152); cmpdst(addr);
|
||||||
|
putln("ADDR=&T"); addr = &t; setdst(t); cmpdst(addr);
|
||||||
|
putln("ADDR=&REC"); addr = &rec; setdst(&rec); cmpdst(addr);
|
||||||
|
putln("ADDR=&REC.NAME"); addr = &rec.name; setdst(&rec.name); cmpdst(addr);
|
||||||
|
putln("ADDR=&REC.INDEX"); addr = &rec.index; setdst(&rec.index); cmpdst(addr);
|
||||||
|
putln("ADDR=&REC.ADDR"); addr = &rec.addr; setdst(&rec.addr); cmpdst(addr);
|
||||||
|
|
||||||
|
anykey();
|
||||||
|
|
||||||
|
puts("GOTO (EOJ)");
|
||||||
|
goto (eoj);
|
||||||
|
failln();
|
||||||
|
goto exit;
|
||||||
|
end:
|
||||||
|
passln();
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
int getend() {
|
||||||
|
return &end;
|
||||||
|
}
|
||||||
|
|
||||||
|
void prtwrd(., yy, xx) {
|
||||||
|
putchr('$'); puthex(yy); puthex(xx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmpdst(yx) {
|
||||||
|
dd = getdst();
|
||||||
|
prtwrd(yx); putchr('='); prtwrd(dd);
|
||||||
|
if (>yx == >dd and <yx == <dd) passln(); else failln();
|
||||||
|
newlin();
|
||||||
|
}
|
55
test/keydefs.c02
Normal file
55
test/keydefs.c02
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/**********************************************
|
||||||
|
* KEYDEFS - Test/Demo for keydefs.h02 module *
|
||||||
|
**********************************************/
|
||||||
|
|
||||||
|
//Specify System Header using -H option
|
||||||
|
#include <keydef.h02>
|
||||||
|
|
||||||
|
char key; //Key value
|
||||||
|
|
||||||
|
main:
|
||||||
|
putstr("PRESS KEYS TO SEE DEFINITIONS"); newlin();
|
||||||
|
while() {
|
||||||
|
key = getchr();
|
||||||
|
if (!key) continue;
|
||||||
|
select (key) {
|
||||||
|
case #KEYBCK: putstr("BACKSPACE");
|
||||||
|
case #KEYBRK: putstr("BREAK");
|
||||||
|
case #KEYCLR: putstr("CLEAR");
|
||||||
|
case #KEYCPY: putstr("COPY");
|
||||||
|
case #KEYDEL: putstr("DELETE");
|
||||||
|
case #KEYDN : putstr("DOWN");
|
||||||
|
case #KEYESC: putstr("ESCAPE");
|
||||||
|
case #KEYFN1: putstr("F1");
|
||||||
|
case #KEYFN2: putstr("F2");
|
||||||
|
case #KEYFN3: putstr("F3");
|
||||||
|
case #KEYFN4: putstr("F4");
|
||||||
|
case #KEYFN5: putstr("F5");
|
||||||
|
case #KEYFN6: putstr("F6");
|
||||||
|
case #KEYFN7: putstr("F7");
|
||||||
|
case #KEYFN8: putstr("F8");
|
||||||
|
case #KEYFN9: putstr("F9");
|
||||||
|
case #KEYFNA: putstr("F10");
|
||||||
|
case #KEYFNB: putstr("F11");
|
||||||
|
case #KEYFNC: putstr("F12");
|
||||||
|
case #KEYHLP: putstr("HELP");
|
||||||
|
case #KEYHOM: putstr("HOME");
|
||||||
|
case #KEYINS: putstr("INSERT");
|
||||||
|
case #KEYLFT: putstr("LEFT");
|
||||||
|
case #KEYRGT: putstr("RIGHT");
|
||||||
|
case #KEYRTN: putstr("RETURN");
|
||||||
|
case #KEYRTS: putstr("SHIFT-RETURN");
|
||||||
|
case #KEYRUN: putstr("RUN");
|
||||||
|
case #KEYRVF: putstr("RVS-OFF");
|
||||||
|
case #KEYRVS: putstr("RVS-ON");
|
||||||
|
case #KEYSPS: putstr("SHIFT-SPACE");
|
||||||
|
case #KEYTAB: putstr("TAB");
|
||||||
|
case #KEYTAS: putstr("SHIFT-TAB");
|
||||||
|
case #KEYUP : putstr("UP");
|
||||||
|
case ' ': putstr("SPACE");
|
||||||
|
default: if (key > ' ' and key <> #DELKEY) putchr(key);
|
||||||
|
}
|
||||||
|
putstr(" ["); prbyte(key); putstr("] ");
|
||||||
|
if (key == #ESCKEY) break;
|
||||||
|
}
|
||||||
|
goto exit;
|
205
test/loops.c02
205
test/loops.c02
|
@ -6,118 +6,115 @@
|
||||||
#include <stddef.h02>
|
#include <stddef.h02>
|
||||||
#include <stdio.h02>
|
#include <stdio.h02>
|
||||||
|
|
||||||
char i, b;
|
char aa,ii; //Function Variables
|
||||||
const char failed = " Test Failed!";
|
char b; //Comparison Variable
|
||||||
|
char i; //Loop Counter
|
||||||
|
|
||||||
|
void putlin() {putstr(); newlin();}
|
||||||
|
void failed() {putlin(" FAILED");}
|
||||||
|
void passed() {putlin(" PASSED");}
|
||||||
|
|
||||||
main:
|
main:
|
||||||
|
putlin("TESTING LOOPS");
|
||||||
|
|
||||||
/* Test If/Goto Loop */
|
/* Test If/Goto Loop */
|
||||||
puts("IF ");
|
putstr("IF ");
|
||||||
i = 0;
|
i = 0;
|
||||||
ifloop:
|
ifloop:
|
||||||
prbyte(i);
|
putchr('0'+i);
|
||||||
putc(' ');
|
i++;
|
||||||
i++;
|
if (i < 8) goto ifloop;
|
||||||
if (i < 10) goto ifloop;
|
if (i=8) passed(); else failed();
|
||||||
newlin();
|
|
||||||
|
|
||||||
/* Test While Loop */
|
/* Test Block If */
|
||||||
puts("WHILE ");
|
putstr("BLOCK ");
|
||||||
i = 0;
|
b = 1;
|
||||||
while (i < 10) {
|
if (b>0) {
|
||||||
prbyte(i);
|
prhex(b);
|
||||||
putc(' ');
|
putstr(" > ");
|
||||||
i++;
|
prhex(0);
|
||||||
}
|
passed();
|
||||||
newlin();
|
}
|
||||||
|
else failed();
|
||||||
|
|
||||||
/* Test Do Loop */
|
putstr(" IF ");
|
||||||
puts("DO ");
|
b = 0;
|
||||||
i = 0;
|
if (b>0) failed();
|
||||||
do {
|
else {
|
||||||
prbyte(i);
|
putchr('0'+i);
|
||||||
putc(' ');
|
putstr(" = ");
|
||||||
i++;
|
prhex(0);
|
||||||
} while (i<10);
|
passed();
|
||||||
newlin();
|
}
|
||||||
|
|
||||||
/* Test For Loop */
|
/* Test While Loop */
|
||||||
puts("FOR ");
|
putstr("WHILE ");
|
||||||
i = 0;
|
i = 0;
|
||||||
for (i=0;i<10;i++) {
|
while (i < 8) {
|
||||||
prbyte(i);
|
putchr('0'+i);
|
||||||
putc(' ');
|
i++;
|
||||||
}
|
}
|
||||||
newlin();
|
if (i=8) passed(); else failed();
|
||||||
|
|
||||||
/* While with Break */
|
/* Test Do Loop */
|
||||||
puts("BREAK ");
|
putstr("DO ");
|
||||||
i = 0;
|
i = 0;
|
||||||
while ($FF) {
|
do {
|
||||||
if (i = 10) break;
|
putchr('0'+i);
|
||||||
prbyte(i);
|
i++;
|
||||||
putc(' ');
|
} while (i<8);
|
||||||
i++;
|
if (i=8) passed(); else failed();
|
||||||
}
|
|
||||||
newlin();
|
|
||||||
|
|
||||||
/* For with Continue */
|
/* Test For Loop */
|
||||||
puts("CONT ");
|
putstr("FOR ");
|
||||||
for (i=0;i<10;i++) {
|
i = 0;
|
||||||
if (i & 1) continue;
|
for (i=0;i<8;i++) {
|
||||||
prbyte(i);
|
putchr('0'+i);
|
||||||
putc(' ');
|
}
|
||||||
}
|
if (i=8) passed(); else failed();
|
||||||
newlin();
|
|
||||||
|
/* While with Break */
|
||||||
|
putstr("BREAK ");
|
||||||
|
i = 0;
|
||||||
|
while ($FF) {
|
||||||
|
if (i = 8) break;
|
||||||
|
putchr('0'+i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i=8) passed(); else failed();
|
||||||
|
|
||||||
|
/* For with Continue */
|
||||||
|
putstr("CONT ");
|
||||||
|
for (i=0;i<16;i++) {
|
||||||
|
if (i & 1) { continue; i=$FF;}
|
||||||
|
putchr('A'+i);
|
||||||
|
}
|
||||||
|
if (i=16) passed(); else failed();
|
||||||
|
|
||||||
/* Test Do with Break and Continue*/
|
/* Test Do with Break and Continue*/
|
||||||
i = 0;
|
i = 0;
|
||||||
puts("DO BC ");
|
putstr("DO BC ");
|
||||||
do {
|
do {
|
||||||
i++;
|
i++;
|
||||||
if (!i&1) continue;
|
if (!i&1) {continue; i=$FF;}
|
||||||
if (i>15) break;
|
if (i>16) break;
|
||||||
prbyte(i);
|
putchr('A'+i);
|
||||||
putc(' ');
|
} while ($FF);
|
||||||
} while ($FF);
|
if (i=17) passed(); else failed();
|
||||||
newlin();
|
|
||||||
|
|
||||||
|
/* Test If/Else, Select in For Loop */
|
||||||
newlin();
|
for(i = 0;i<4;i++) {
|
||||||
|
select (i) {
|
||||||
/* Test Block If */
|
case 0: putstr("FOR "); b=0;
|
||||||
putln("BLOCK IF");
|
case 1: putstr(" IF "); b=1;
|
||||||
b = 1;
|
case 2: putstr(" ELSE "); b=2;
|
||||||
if (b>0) {
|
case 3: putstr(" SELECT "); b=3;
|
||||||
prbyte(b);
|
default: putstr(" ERROR! "); b=$FF;
|
||||||
puts(" is greater than ");
|
}
|
||||||
prbyte(0);
|
putchr('0'+i);
|
||||||
newlin();
|
if (i & 1) putstr("-ODD "); else putstr("-EVEN");
|
||||||
}
|
if (i=b) passed(); else failed();
|
||||||
else
|
}
|
||||||
putln(&failed);
|
|
||||||
b = 0;
|
putlin("ALL TESTS COMPLETE");
|
||||||
if (b>0) {
|
goto exit;
|
||||||
putln(&failed);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
prbyte(b);
|
|
||||||
puts(" is equal to ");
|
|
||||||
prbyte(0);
|
|
||||||
newlin();
|
|
||||||
}
|
|
||||||
newlin();
|
|
||||||
|
|
||||||
/* Test If/Else in For Loop */
|
|
||||||
putln("FOR/IF/ELSE");
|
|
||||||
for(i = 0;i<4;i++) {
|
|
||||||
prbyte(i);
|
|
||||||
if (i & 1)
|
|
||||||
putln(" is odd");
|
|
||||||
else
|
|
||||||
putln(" is even");
|
|
||||||
}
|
|
||||||
newlin();
|
|
||||||
|
|
||||||
|
|
||||||
goto exit;
|
|
||||||
|
|
35
test/orao.bat
Normal file
35
test/orao.bat
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
@REM Compile and Assemble Program for Orao
|
||||||
|
@ECHO OFF
|
||||||
|
|
||||||
|
SET ORAOBIN=C:\Programs\OraoEmulator\bin
|
||||||
|
SET ORAOTAP=C:\Programs\OraoEmulator\tap
|
||||||
|
SET ORAOWAV=C:\Programs\OraoPy\wav
|
||||||
|
SET ORAOTOOLS=C:\Programs\OraoEmulator\tools
|
||||||
|
|
||||||
|
IF EXIST %1.c02 GOTO COMPILE
|
||||||
|
ECHO File %1.c02 not found
|
||||||
|
EXIT /B
|
||||||
|
|
||||||
|
:COMPILE
|
||||||
|
ECHO Compiling File %1.c02
|
||||||
|
..\c02.exe -h orao -s orao %1 >%1.dbg
|
||||||
|
IF ERRORLEVEL 1 EXIT /B
|
||||||
|
|
||||||
|
ECHO Assembling File %1.asm
|
||||||
|
dasm %1.asm -f1 -o%1.obj -l%1.lst -s%1.sym
|
||||||
|
IF ERRORLEVEL 1 EXIT /B
|
||||||
|
|
||||||
|
ECHO Creating Binary File
|
||||||
|
%ORAOTOOLS%\obj2bin %1.obj %ORAOBIN%\%1.bin
|
||||||
|
IF ERRORLEVEL 1 EXIT /B
|
||||||
|
|
||||||
|
ECHO Building Tape Image
|
||||||
|
%ORAOTOOLS%\maketap %ORAOTAP%\%1.tap %ORAOBIN%\%1.bin
|
||||||
|
IF ERRORLEVEL 1 EXIT /B
|
||||||
|
|
||||||
|
ECHO Building WAV File
|
||||||
|
%ORAOTOOLS%\orao2wav %ORAOBIN%\%1.bin
|
||||||
|
IF ERRORLEVEL 1 EXIT /B
|
||||||
|
MOVE %ORAOBIN%\%1.wav %ORAOWAV%
|
||||||
|
|
||||||
|
DEL %1.obj
|
71
test/scrntst.c02
Normal file
71
test/scrntst.c02
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/************************************
|
||||||
|
* SCRNTST - Test C02 screen module *
|
||||||
|
************************************/
|
||||||
|
|
||||||
|
//use -h amd -s options on command line
|
||||||
|
#include <screen.h02>
|
||||||
|
|
||||||
|
char col, row, wdth, hght;
|
||||||
|
char mode, modex;
|
||||||
|
char a, c, f, i, m;
|
||||||
|
char aa, yy;
|
||||||
|
|
||||||
|
const char modes = {#SMTEXT, #SMWIDE};
|
||||||
|
|
||||||
|
void prtaxy(aa,yy) {
|
||||||
|
if (aa & $F0) prbyte(aa); else prhex(aa);
|
||||||
|
putchr('X');
|
||||||
|
if (yy & $F0) prbyte(yy); else prhex(yy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void putlin() {putstr(); newlin();}
|
||||||
|
|
||||||
|
main:
|
||||||
|
|
||||||
|
for (modex=0; modex<@modes; modex++) {
|
||||||
|
|
||||||
|
mode = modes[modex];
|
||||||
|
if (mode == $FF) continue; //Unsupported Mode
|
||||||
|
|
||||||
|
if (setscr(mode)=$FF) putlin("ERROR IN SETSCR()");
|
||||||
|
m = getscr();
|
||||||
|
if (m <> mode) putlin("ERROR IN GETSCR()");
|
||||||
|
putstr("MODE="); prbyte(m); newlin();
|
||||||
|
|
||||||
|
wdth, hght = getsiz(); //Get Screen Width & Height
|
||||||
|
prtaxy(wdth,hght); newlin();
|
||||||
|
|
||||||
|
for (i=1; i<6; i++) putchr('.');
|
||||||
|
col, row = getpos(); //Get Cursor Position
|
||||||
|
prtaxy(col,row);
|
||||||
|
crsrhm(); prtaxy(getpos());
|
||||||
|
getchr(); newlin(); //Wait For keypress
|
||||||
|
|
||||||
|
clrscr(); //Clear Screen
|
||||||
|
col, row = getpos(); //Get Cursor Position
|
||||||
|
prtaxy(col, row);
|
||||||
|
f = (col == 255) ? 0 : $FF;
|
||||||
|
getchr();
|
||||||
|
|
||||||
|
if (f) clrscr(); else newlin();
|
||||||
|
|
||||||
|
if (wdth:- or hght:-) goto exit;
|
||||||
|
for (c='@'; c<'`'; c++) {
|
||||||
|
if (!f) newlin();
|
||||||
|
for (row=hght-2; row; row--) {
|
||||||
|
if (!f) putchr(' ');
|
||||||
|
for (col=wdth-2; col; col--) {
|
||||||
|
if (f) setpos(col,row);
|
||||||
|
putchr(c);
|
||||||
|
}
|
||||||
|
if (!f) newlin();
|
||||||
|
if (getkey() == #ESCKEY) goto exit;
|
||||||
|
}
|
||||||
|
if (!f) getchr();
|
||||||
|
}
|
||||||
|
if (f) getchr(); //Wait For keypress
|
||||||
|
newlin();
|
||||||
|
|
||||||
|
} //for modex
|
||||||
|
|
||||||
|
goto exit;
|
80
test/sdeftest.c02
Normal file
80
test/sdeftest.c02
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/**************************************
|
||||||
|
* SDEFTEST - Test Library stddef.h02 *
|
||||||
|
**************************************/
|
||||||
|
|
||||||
|
//use -h option on command line
|
||||||
|
#include <stddef.h02>
|
||||||
|
|
||||||
|
char lo,hi;
|
||||||
|
char aa,hh,ll,xx,yy;
|
||||||
|
int dstadr,srcadr;
|
||||||
|
|
||||||
|
void clrdst() {dstlo=0; dsthi=0;}
|
||||||
|
void clrreg() {return 0,0,0;}
|
||||||
|
void clrtmp() {temp0=0; temp1=0; temp2=0; temp3=0;}
|
||||||
|
void clrsrc() {srclo=0; srchi=0;}
|
||||||
|
void prskey() {putstr(" PRESS ANY KEY"); newlin(); getchr(); newlin();}
|
||||||
|
void prtcma(aa) {putchr(','); prbyte(aa);}
|
||||||
|
void prtdhl() {ll=dstlo; hh=dsthi; putstr(" DSTHI,LO="); prbyte(hh); prtcma(ll); newlin();}
|
||||||
|
void prtdst() {prbyte(dsthi);prbyte(dstlo); newlin();}
|
||||||
|
void prtlin() {putstr(); newlin();}
|
||||||
|
void prtreg(aa,yy,xx) {putstr(" A,X,Y="); prbyte(aa); prtcma(yy); prtcma(xx); newlin();}
|
||||||
|
void prtsav() {putstr(" TEMP1,2="); prtcma(temp1); prtcma(temp2); newlin();}
|
||||||
|
void prtshl() {ll=srclo; hh=srchi; putstr(" SRCHI,LO="); prbyte(hh); prtcma(ll); newlin();}
|
||||||
|
void prtsrc() {prbyte(srchi);prbyte(srclo); newlin();}
|
||||||
|
void prttmp() {putstr(" TEMP0,1,2="); prbyte(temp0); prtcma(temp1); prtcma(temp2); newlin();}
|
||||||
|
void prtwrd(.,yy,xx) {prbyte(yy); prbyte(xx); newlin();}
|
||||||
|
void setreg(aa,yy,xx) {}
|
||||||
|
|
||||||
|
main:
|
||||||
|
newlin();
|
||||||
|
|
||||||
|
putstr("#TRUE="); prbyte(#TRUE);
|
||||||
|
putstr(", #FALSE="); prbyte(#FALSE); newlin();
|
||||||
|
newlin();
|
||||||
|
|
||||||
|
prtlin("SAVREG($A,$B,$C)"); clrtmp(); savreg($A,$B,$C); prttmp();
|
||||||
|
prtlin("RESREG()"); clrreg(); prtreg(resreg());
|
||||||
|
prtlin("SAVRXY($D,$E,$F)"); clrtmp(); savrxy($D,$E,$F); prttmp();
|
||||||
|
prtlin("RESRXY()"); clrreg(); prtreg(resrxy());
|
||||||
|
newlin();
|
||||||
|
|
||||||
|
prtlin("SAVRXY(&$1234)"); putstr(" ADDTXY(&$5678)=$");
|
||||||
|
savrxy(&$1234); prtwrd(addtxy(&$5678));
|
||||||
|
prtlin("SAVRXY(&$1234)"); putstr(" SUBTXY(&$68AC)=$");
|
||||||
|
savrxy(&$1234); prtwrd(subtxy(&$68AC));
|
||||||
|
newlin();
|
||||||
|
|
||||||
|
putstr("DECRXY(&$0000)=$"); prtwrd(decrxy(&$0000));
|
||||||
|
putstr("INCRXY(&$FFFF)=$"); prtwrd(incrxy(&$FFFF));
|
||||||
|
newlin();
|
||||||
|
|
||||||
|
prskey();
|
||||||
|
|
||||||
|
prtlin("SETSRC(&$1234)"); clrsrc(); setsrc(&$1234); savsrc();
|
||||||
|
prtshl(); prtlin("SAVSRC()"); prtsav();
|
||||||
|
prtlin("RESSRC()"); clrsrc(); ressrc(); srcadr=getsrc();
|
||||||
|
prtshl(); putstr("GETSRC()="); prtwrd(srcadr);
|
||||||
|
prtlin("SETDSS()"); clrdst(); ressrc(); setdss(); prtdhl();
|
||||||
|
newlin();
|
||||||
|
|
||||||
|
prtlin("SETDST(&$5678)"); clrdst(); setdst(&$5678);savdst();
|
||||||
|
prtdhl(); prtlin("SAVDST()"); prtsav();
|
||||||
|
prtlin("RESDST()"); clrdst(); resdst(); dstadr=getdst();
|
||||||
|
prtdhl(); putstr("GETSRC()="); prtwrd(dstadr);
|
||||||
|
prtlin("SETSRD()"); clrsrc(); resdst(); setsrd(); prtshl();
|
||||||
|
newlin();
|
||||||
|
|
||||||
|
prskey();
|
||||||
|
|
||||||
|
prtlin("SETSRC(&$0FFF)"); putstr(" ADDSRA($FF)=$");
|
||||||
|
setsrc(&$0FFF); addsra($FF); prtsrc();
|
||||||
|
prtlin("SETSRC(&$1234)"); putstr(" ADDSRC(&$CDEF)=$");
|
||||||
|
setsrc(&$1234); addsrc(&$CDEF); prtsrc();
|
||||||
|
prtlin("SETDST(&$0FFF)"); putstr(" ADDDSA($FF)=$");
|
||||||
|
setdst(&$0FFF); adddsa($FF); prtdst();
|
||||||
|
prtlin("SETDST(&$1234)"); putstr(" ADDDST(&$CDEF)=$");
|
||||||
|
setdst(&$1234); adddst(&$CDEF); prtdst();
|
||||||
|
newlin();
|
||||||
|
|
||||||
|
goto exit;
|
231
test/slibtest.c02
Normal file
231
test/slibtest.c02
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
/**************************************************
|
||||||
|
* TESTSLIB - Test Library stdlib.h02 for py65mon *
|
||||||
|
**************************************************/
|
||||||
|
|
||||||
|
//Specify System Header using -H option
|
||||||
|
#include <stddef.h02>
|
||||||
|
#include <stdlib.h02>
|
||||||
|
|
||||||
|
char aa, yy, xx;
|
||||||
|
|
||||||
|
void prtcma(aa) {putchr(','); prbyte(aa);}
|
||||||
|
void prtlin() {putstr(); newlin();}
|
||||||
|
void prtok() {prtlin(" OK");}
|
||||||
|
void prtopr(aa,yy,xx) {prbyte(aa); putchr(yy); prbyte(xx); putchr("=");}
|
||||||
|
|
||||||
|
main:
|
||||||
|
|
||||||
|
tstabs: //Test abs()
|
||||||
|
char onum, anum, cnum;
|
||||||
|
|
||||||
|
putstr("ABS()");
|
||||||
|
onum = 0;
|
||||||
|
do { //test abs() positive numbers
|
||||||
|
anum = abs(onum);
|
||||||
|
if (onum <> anum) goto abserr;
|
||||||
|
onum++;
|
||||||
|
} while (onum < $80);
|
||||||
|
do { //test abs() negative numbers
|
||||||
|
anum = abs(onum);
|
||||||
|
cnum = -onum;
|
||||||
|
if (anum <> cnum) goto abserr;
|
||||||
|
onum++;
|
||||||
|
} while (onum);
|
||||||
|
prtok();
|
||||||
|
|
||||||
|
tstmnx: //Test min() and max()
|
||||||
|
char lnum, rnum, nnum, xnum;
|
||||||
|
|
||||||
|
putstr("MAX(), MIN()");
|
||||||
|
lnum = 0; do {
|
||||||
|
rnum = 0; do {
|
||||||
|
xnum = max(lnum,rnum);
|
||||||
|
nnum = min(lnum,rnum);
|
||||||
|
if (lnum > rnum) {
|
||||||
|
if (xnum <> lnum) maxerr();
|
||||||
|
if (nnum <> rnum) minerr();
|
||||||
|
} else {
|
||||||
|
if (xnum <> rnum) maxerr();
|
||||||
|
if (nnum <> lnum) minerr();
|
||||||
|
}
|
||||||
|
} while (rnum);
|
||||||
|
} while (lnum);
|
||||||
|
prtok();
|
||||||
|
|
||||||
|
tstmlt: //Test mult()
|
||||||
|
char mltplr, mltpnd, acmlsb, acmmsb, acmlst;
|
||||||
|
char prodct, ovrflw;
|
||||||
|
|
||||||
|
putstr("MULT()");
|
||||||
|
mltplr = 1;
|
||||||
|
do {
|
||||||
|
if (!mltplr & $F) putchr('.');
|
||||||
|
mltpnd = 1; acmlst = 0;
|
||||||
|
acmlsb = 0; acmmsb = 0;
|
||||||
|
do {
|
||||||
|
acmlsb = acmlsb + mltplr;
|
||||||
|
if (acmlsb<acmlst) acmmsb++;
|
||||||
|
acmlst = acmlsb;
|
||||||
|
prodct,ovrflw = mult(mltplr,mltpnd);
|
||||||
|
if (prodct <> acmlsb) goto mlterr;
|
||||||
|
mltpnd++;
|
||||||
|
} while (mltpnd);
|
||||||
|
mltplr++;
|
||||||
|
} while (mltplr);
|
||||||
|
prtok();
|
||||||
|
|
||||||
|
tstdiv: //Test div()
|
||||||
|
char maxmpd, divdnd, divisr, quotnt;
|
||||||
|
|
||||||
|
putstr("DIV()");
|
||||||
|
mltplr = 255;
|
||||||
|
maxmpd = 1;
|
||||||
|
drloop:
|
||||||
|
mltpnd = 1;
|
||||||
|
acmlsb = 0;
|
||||||
|
ddloop:
|
||||||
|
acmlsb = acmlsb + mltplr;
|
||||||
|
prodct = mult(mltplr, mltpnd);
|
||||||
|
quotnt = div(prodct, mltpnd);
|
||||||
|
if (quotnt <> mltplr) goto derror;
|
||||||
|
mltpnd++;
|
||||||
|
if (mltpnd < maxmpd) goto ddloop;
|
||||||
|
mltplr>>;
|
||||||
|
maxmpd<<;
|
||||||
|
if (mltplr <> 0) goto drloop;
|
||||||
|
prtok();
|
||||||
|
|
||||||
|
tstrnd: //Test rand() and rands()
|
||||||
|
char countr, rndnum, rndtbl[255];
|
||||||
|
|
||||||
|
putstr("RAND()");
|
||||||
|
rands(1); //Seed Random Number Generator;
|
||||||
|
|
||||||
|
countr = 0;
|
||||||
|
|
||||||
|
riloop:
|
||||||
|
rndtbl[countr] = 0;
|
||||||
|
countr++;
|
||||||
|
if (countr <> 0) goto riloop;
|
||||||
|
|
||||||
|
rnloop:
|
||||||
|
rndnum = rand();
|
||||||
|
if (rndtbl[rndnum] > 0) goto rnderr;
|
||||||
|
rndtbl[rndnum] = $FF;
|
||||||
|
countr++;
|
||||||
|
if (countr < 255) goto rnloop;
|
||||||
|
prtok();
|
||||||
|
|
||||||
|
tstros: //Test rotatl(), rotatr(), swap()
|
||||||
|
char lbyte, rbyte, obyte, sbyte, tbyte, scount;
|
||||||
|
|
||||||
|
putstr("ROTATL(), SHIFTL()");
|
||||||
|
obyte = 0;
|
||||||
|
do {
|
||||||
|
if (!obyte & $F) putchr('.');
|
||||||
|
scount = 0; sbyte = obyte; tbyte = obyte;
|
||||||
|
do {
|
||||||
|
rbyte = rotatl(obyte, scount); if (rbyte <> tbyte) goto rtlerr;
|
||||||
|
lbyte = shiftl(obyte, scount); if (lbyte <> sbyte) goto shlerr;
|
||||||
|
sbyte<<;
|
||||||
|
temp0 = tbyte; tbyte<<; if (temp0:-) tbyte++;
|
||||||
|
scount++; if (scount == 8) scount = $F8;
|
||||||
|
} while (scount);
|
||||||
|
obyte ++;
|
||||||
|
} while (obyte);
|
||||||
|
prtok();
|
||||||
|
|
||||||
|
putstr("ROTATR(), SHIFTR()");
|
||||||
|
obyte = 0;
|
||||||
|
do {
|
||||||
|
if (!obyte & $F) putchr('.');
|
||||||
|
scount = 0; sbyte = obyte; tbyte = obyte;
|
||||||
|
do {
|
||||||
|
rbyte = rotatr(obyte, scount); if (rbyte <> tbyte) goto rtrerr;
|
||||||
|
lbyte = shiftr(obyte, scount); if (lbyte <> sbyte) goto shrerr;
|
||||||
|
sbyte>>;
|
||||||
|
temp0 = tbyte; tbyte>>; if (temp0 & 1) tbyte = tbyte | $80;
|
||||||
|
scount++; if (scount == 8) scount = $F8;
|
||||||
|
} while (scount);
|
||||||
|
obyte ++;
|
||||||
|
} while (obyte);
|
||||||
|
prtok();
|
||||||
|
|
||||||
|
putstr("SWAP()");
|
||||||
|
lbyte=0; do {
|
||||||
|
rbyte = 0; do {
|
||||||
|
obyte = lbyte & $f0; obyte = rbyte & $0f + lbyte;
|
||||||
|
tbyte = lbyte & $0f; tbyte = rbyte & $f0 + lbyte;
|
||||||
|
sbyte = swap(obyte);
|
||||||
|
if (sbyte <> tbyte) goto swperr;
|
||||||
|
rbyte = rbyte + $11;
|
||||||
|
} while (rbyte & $0f);
|
||||||
|
} while (lbyte & $0f);
|
||||||
|
prtok();
|
||||||
|
|
||||||
|
tstc2a: //Test ctoa();
|
||||||
|
char srcchr, dstchr, tststr[4];
|
||||||
|
|
||||||
|
putstr("ATOC(), CTOA()");
|
||||||
|
srcchr = 0; do {
|
||||||
|
ctoa(srcchr, &tststr);
|
||||||
|
dstchr = atoc(&tststr);
|
||||||
|
if (srcchr <> dstchr) goto c2aerr;
|
||||||
|
srcchr++;
|
||||||
|
} while (srcchr);
|
||||||
|
prtok();
|
||||||
|
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
abserr:
|
||||||
|
putstr("ABS("); prbyte(onum); putstr(")="); prbyte(anum); prtcma(cnum); newlin();
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
maxerr:
|
||||||
|
putstr("MAX("); prbyte(lnum); prtcma(rnum); putstr(")="); prbyte(xnum); newlin();
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
minerr:
|
||||||
|
putstr("MIN("); prbyte(lnum); prtcma(rnum); putstr(")="); prbyte(nnum); newlin();
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
mlterr:
|
||||||
|
newlin(); prtopr(mltplr,'*',mltpnd); prbyte(prodct); prtcma(acmlsb); newlin();
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
derror:
|
||||||
|
newlin(); prtopr(divdnd,'/',divisr); prbyte(quotnt); prtcma(mltplr); newlin();
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
rnderr:
|
||||||
|
newlin(); putstr("RAND()="); prbyte(rndnum); prtcma(countr); newlin();
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
rtlerr:
|
||||||
|
newlin(); putstr("ROTATL("); prbyte(obyte); prtcma(scount); putstr(")=");
|
||||||
|
prbyte(rbyte); prtcma(tbyte); newlin();
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
rtrerr:
|
||||||
|
newlin(); putstr("ROTATR("); prbyte(obyte); prtcma(scount); putstr(")=");
|
||||||
|
prbyte(rbyte); prtcma(tbyte); newlin();
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
shlerr:
|
||||||
|
newlin(); putstr("SHIFTL("); prbyte(obyte); prtcma(scount); putstr(")=");
|
||||||
|
prbyte(lbyte); prtcma(sbyte); newlin();
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
shrerr:
|
||||||
|
newlin(); putstr("SHIFTR("); prbyte(obyte); prtcma(scount); putstr(")=");
|
||||||
|
prbyte(lbyte); prtcma(sbyte); newlin();
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
swperr:
|
||||||
|
newlin(); putstr("SWAP("); prbyte(obyte); putstr(")=");
|
||||||
|
prbyte(sbyte); prtcma(tbyte); newlin();
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
c2aerr:
|
||||||
|
putstr("CTOA("); prbyte(srcchr); putstr(")="); prbyte(dstchr); newlin();
|
||||||
|
goto exit;
|
105
test/testilib.c02
Normal file
105
test/testilib.c02
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
/****************************************************
|
||||||
|
* INTS - Test Integer Variables and Function Calls */
|
||||||
|
|
||||||
|
//Specify System Header using -H option
|
||||||
|
#include <screen.h02>
|
||||||
|
#include <stddef.h02>
|
||||||
|
#include <stdlib.h02>
|
||||||
|
#include <intlib.h02>
|
||||||
|
#include <stdio.h02>
|
||||||
|
#include <stdiox.h02>
|
||||||
|
#include <string.h02>
|
||||||
|
#include <test.h02>
|
||||||
|
|
||||||
|
char size;
|
||||||
|
char s[128]; //Test String
|
||||||
|
|
||||||
|
int ivar,ival; //Integer Variables
|
||||||
|
int icmp,itot,ires; //Function Variables
|
||||||
|
int less, more; //Test Values for imin() and imax()
|
||||||
|
|
||||||
|
int yx, dd; //Function Arguments and Variables
|
||||||
|
|
||||||
|
void cpival(icmp) {
|
||||||
|
if (>ival <> >icmp or <ival <> <icmp) {
|
||||||
|
putwrd(ival); puts("<>"); putwrd(icmp);
|
||||||
|
failln();
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test imin() and imax() */
|
||||||
|
void minmax() {
|
||||||
|
newlin();
|
||||||
|
puts("LESS=$"); putwrd(less); puts(",MORE=$"); putwrd(more); newlin();
|
||||||
|
puts(" IMIN()=$"); setsrc(less);
|
||||||
|
ival = imin(more); putwrd(ival); newlin();
|
||||||
|
cpival(less);
|
||||||
|
puts(" IMAX()=$"); setsrc(less);
|
||||||
|
ival = imax(more); putwrd(ival); newlin();
|
||||||
|
cpival(more);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test cvibcd() and upbcdi() */
|
||||||
|
void intbcd(ival) {
|
||||||
|
newlin(); puts("CVIBCD($"); putwrd(ival); puts(")=$");
|
||||||
|
cvibcd(ival); puthex(temp2); puthex(temp1); puthex(temp0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test itoa() and atoi() */
|
||||||
|
void itaati(ivar) {
|
||||||
|
newlin();
|
||||||
|
puts("ITOA($"); putwrd(ivar); puts(")=\"");
|
||||||
|
setdst(s); size = itoa(ivar); puts(s); putln("\"");
|
||||||
|
puts("ATOI(\""); puts(s); puts("\")=$");
|
||||||
|
ival = atoi(s); putwrd(ival); newlin();
|
||||||
|
//cpival(ivar);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test iadd() and isub() */
|
||||||
|
void addsub(ivar) {
|
||||||
|
newlin();
|
||||||
|
putint(ival); putchr('+'); putint(ivar); putchr('=');
|
||||||
|
setsrc(ival); itot = iadd(ivar); putint(itot); newlin();
|
||||||
|
putint(itot); putchr('-'); putint(ivar); putchr('=');
|
||||||
|
setsrc(itot); ires = isub(ivar); putint(ires); newlin();
|
||||||
|
cpival(ires);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test imult() and idiv() */
|
||||||
|
void mltdiv(ivar) {
|
||||||
|
newlin();
|
||||||
|
putint(ival); putchr('X'); putint(ivar); putchr('=');
|
||||||
|
setsrc(ival); itot = imult(ivar); putint(itot); newlin();
|
||||||
|
putint(itot); putchr('/'); putint(ivar); putchr('=');
|
||||||
|
setsrc(itot); ires = idiv(ivar); putint(ires); newlin();
|
||||||
|
cpival(ires);
|
||||||
|
}
|
||||||
|
|
||||||
|
main:
|
||||||
|
|
||||||
|
less = $009A; more = $00DE; minmax();
|
||||||
|
less = $789A; more = $78DE; minmax();
|
||||||
|
less = $7800; more = $BC00; minmax();
|
||||||
|
less = $789A; more = $BCDE; minmax();
|
||||||
|
anykey();
|
||||||
|
|
||||||
|
itaati(&0);
|
||||||
|
itaati(&234);
|
||||||
|
itaati(&256);
|
||||||
|
itaati(&456);
|
||||||
|
itaati(&23456);
|
||||||
|
itaati(&$FFFF);
|
||||||
|
anykey();
|
||||||
|
|
||||||
|
ival = &23; addsub(&34);
|
||||||
|
ival = &1234; addsub(&5678);
|
||||||
|
ival = &23456; addsub(&34567);
|
||||||
|
ival = &$7700; addsub(&$6600);
|
||||||
|
ival = &$7FFF; addsub(&$8000);
|
||||||
|
anykey();
|
||||||
|
|
||||||
|
//ival = &123; mltdiv(&234);
|
||||||
|
|
||||||
|
|
||||||
|
goto exit;
|
|
@ -1,53 +0,0 @@
|
||||||
/************************************
|
|
||||||
* TESTHDR - Test C02 screen module *
|
|
||||||
************************************/
|
|
||||||
|
|
||||||
//use -h amd -s options on command line
|
|
||||||
#include <screen.h02>
|
|
||||||
|
|
||||||
char col, row, wdth, hght;
|
|
||||||
char c, f, i, aa, yy;
|
|
||||||
|
|
||||||
void prtaxy(aa,yy) {
|
|
||||||
if (aa & $F0) prbyte(aa); else prhex(aa);
|
|
||||||
putchr('X');
|
|
||||||
if (yy & $F0) prbyte(yy); else prhex(yy);
|
|
||||||
}
|
|
||||||
|
|
||||||
main:
|
|
||||||
|
|
||||||
wdth, hght = getsiz(); //Get Screen Width & Height
|
|
||||||
prtaxy(wdth,hght); newlin();
|
|
||||||
|
|
||||||
for (i=1; i<6; i++) putchr('.');
|
|
||||||
col, row = getpos(); //Get Cursor Position
|
|
||||||
prtaxy(col,row);
|
|
||||||
crsrhm(); prtaxy(getpos());
|
|
||||||
getchr(); newlin(); //Wait For keypress
|
|
||||||
|
|
||||||
clrscr(); //Clear Screen
|
|
||||||
col, row = getpos(); //Get Cursor Position
|
|
||||||
prtaxy(col, row);
|
|
||||||
f = (col == 255) ? 0 : $FF;
|
|
||||||
getchr();
|
|
||||||
|
|
||||||
if (f) clrscr(); else newlin();
|
|
||||||
|
|
||||||
if (wdth:- or hght:-) goto exit;
|
|
||||||
for (c='@'; c<'`'; c++) {
|
|
||||||
if (!f) newlin();
|
|
||||||
for (row=hght-2; row; row--) {
|
|
||||||
if (!f) putchr(' ');
|
|
||||||
for (col=wdth-2; col; col--) {
|
|
||||||
if (f) setpos(col,row);
|
|
||||||
putchr(c);
|
|
||||||
}
|
|
||||||
if (!f) newlin();
|
|
||||||
if (getkey() == #ESCKEY) goto exit;
|
|
||||||
}
|
|
||||||
if (!f) getchr();
|
|
||||||
}
|
|
||||||
if (f) getchr(); //Wait For keypress
|
|
||||||
newlin();
|
|
||||||
|
|
||||||
goto exit;
|
|
|
@ -1,82 +0,0 @@
|
||||||
/************************************************
|
|
||||||
* TESTSD - Test Library stddef.h02 for py65mon *
|
|
||||||
************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
//use -h option on command line
|
|
||||||
#include <stddef.h02>
|
|
||||||
|
|
||||||
const char txtstr = {
|
|
||||||
"#TRUE=",", #FALSE=",
|
|
||||||
"SAVREG($A,$B,$C)", " TEMP0,1,2=",
|
|
||||||
"RESREG()", " A,X,Y=",
|
|
||||||
"SETSRC(&$1234)"," SRCLO,HI=", " GETSRC()=",
|
|
||||||
"SETDST(&$5678)"," DSTLO,HI=", " GETDST()="
|
|
||||||
};
|
|
||||||
char txtidx;
|
|
||||||
|
|
||||||
char aa,xx,yy;
|
|
||||||
|
|
||||||
main:
|
|
||||||
txtidx = 0;
|
|
||||||
newlin();
|
|
||||||
|
|
||||||
prttxt(); prbyte(#TRUE);
|
|
||||||
prttxt(); prbyte(#FALSE);
|
|
||||||
newlin(); newlin();
|
|
||||||
|
|
||||||
temp0=0; temp1=0; temp3 = 0;
|
|
||||||
prtlin(); savreg($A,$B,$C);
|
|
||||||
prttxt(); prbyte(temp0);
|
|
||||||
prtcma(); prbyte(temp1);
|
|
||||||
prtcma(); prbyte(temp2);
|
|
||||||
newlin();
|
|
||||||
|
|
||||||
setreg(0,0,0);
|
|
||||||
prtlin(); aa,yy,xx = resreg();
|
|
||||||
prttxt(); prbyte(aa);
|
|
||||||
prtcma(); prbyte(yy);
|
|
||||||
prtcma(); prbyte(xx);
|
|
||||||
newlin(); newlin();
|
|
||||||
|
|
||||||
|
|
||||||
srclo = 0; srchi = 0;
|
|
||||||
prtlin(); setsrc(&$1234);
|
|
||||||
prttxt(); prbyte(srclo);
|
|
||||||
prtcma(); prbyte(srchi);
|
|
||||||
newlin();
|
|
||||||
prttxt(); setreg(0,0,0);
|
|
||||||
getsrc(); prtwrd();
|
|
||||||
newlin(); newlin();
|
|
||||||
|
|
||||||
dstlo = 0; dsthi = 0;
|
|
||||||
prtlin(); setdst(&$5678);
|
|
||||||
prttxt(); prbyte(dstlo);
|
|
||||||
prtcma(); prbyte(dsthi);
|
|
||||||
newlin();
|
|
||||||
prttxt(); setreg(0,0,0);
|
|
||||||
getdst(); prtwrd();
|
|
||||||
newlin(); newlin();
|
|
||||||
|
|
||||||
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
void setreg(aa,yy,xx) {}
|
|
||||||
|
|
||||||
void prtwrd(aa,yy,xx) {
|
|
||||||
prbyte(yy);
|
|
||||||
prbyte(xx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void prtcma() {prchr(',');}
|
|
||||||
|
|
||||||
void prtlin() {prttxt(); newlin();}
|
|
||||||
|
|
||||||
void prttxt() {
|
|
||||||
while (txtstr[txtidx]) {
|
|
||||||
//prbyte(txtidx);prchr(' ');
|
|
||||||
prchr(txtstr[txtidx]);
|
|
||||||
txtidx++;
|
|
||||||
}
|
|
||||||
txtidx++;
|
|
||||||
}
|
|
220
test/testsl.c02
220
test/testsl.c02
|
@ -1,220 +0,0 @@
|
||||||
/************************************************
|
|
||||||
* TESTSL - Test Library stdlib.h02 for py65mon *
|
|
||||||
************************************************/
|
|
||||||
|
|
||||||
//Specify System Header using -H option
|
|
||||||
#include <stddef.h02>
|
|
||||||
#include <stdlib.h02>
|
|
||||||
|
|
||||||
main:
|
|
||||||
|
|
||||||
tstabs: //Test abs()
|
|
||||||
char onum, anum, cnum;
|
|
||||||
|
|
||||||
prchr('A');
|
|
||||||
prchr('B');
|
|
||||||
prchr('S');
|
|
||||||
prchr(' ');
|
|
||||||
|
|
||||||
//test abs() positive numbers
|
|
||||||
onum = 0;
|
|
||||||
aploop:
|
|
||||||
anum = abs(onum);
|
|
||||||
if (onum <> anum) goto abserr;
|
|
||||||
onum++;
|
|
||||||
if (onum < $80) goto aploop;
|
|
||||||
|
|
||||||
//test abs() negative numbers
|
|
||||||
anloop:
|
|
||||||
anum = abs(onum);
|
|
||||||
cnum = -onum;
|
|
||||||
if (anum <> cnum) goto abserr;
|
|
||||||
onum++;
|
|
||||||
if (onum > $00) goto anloop;
|
|
||||||
prchr('O');
|
|
||||||
prchr('K');
|
|
||||||
newlin();
|
|
||||||
|
|
||||||
tstmlt: //Test mult()
|
|
||||||
char mltplr, mltpnd, acmlsb, acmmsb, acmlst;
|
|
||||||
char prodct, ovrflw;
|
|
||||||
|
|
||||||
mltplr = 1;
|
|
||||||
mrloop:
|
|
||||||
prbyte(mltplr);
|
|
||||||
mltpnd = 1; acmlst = 0;
|
|
||||||
acmlsb = 0; acmmsb = 0;
|
|
||||||
mdloop:
|
|
||||||
acmlsb = acmlsb + mltplr;
|
|
||||||
if (acmlsb<acmlst) acmmsb++;
|
|
||||||
acmlst = acmlsb;
|
|
||||||
prodct,ovrflw = mult(mltplr,mltpnd);
|
|
||||||
if (prodct <> acmlsb) goto merror;
|
|
||||||
//if (ovrflw <> acmmsb) goto merror;
|
|
||||||
mltpnd++;
|
|
||||||
if (mltpnd > 0) goto mdloop;
|
|
||||||
mltplr++;
|
|
||||||
if (mltplr > 0) goto mrloop;
|
|
||||||
newlin();
|
|
||||||
prchr('M');
|
|
||||||
prchr('U');
|
|
||||||
prchr('L');
|
|
||||||
prchr('T');
|
|
||||||
prchr(' ');
|
|
||||||
prchr('O');
|
|
||||||
prchr('K');
|
|
||||||
newlin();
|
|
||||||
|
|
||||||
tstdiv: //Test div()
|
|
||||||
char maxmpd, divdnd, divisr, quotnt;
|
|
||||||
|
|
||||||
mltplr = 255;
|
|
||||||
maxmpd = 1;
|
|
||||||
drloop:
|
|
||||||
prbyte(mltplr);
|
|
||||||
mltpnd = 1;
|
|
||||||
acmlsb = 0;
|
|
||||||
ddloop:
|
|
||||||
prbyte(mltpnd);
|
|
||||||
acmlsb = acmlsb + mltplr;
|
|
||||||
prodct = mult(mltplr, mltpnd);
|
|
||||||
quotnt = div(prodct, mltpnd);
|
|
||||||
if (quotnt <> mltplr) goto derror;
|
|
||||||
mltpnd++;
|
|
||||||
if (mltpnd < maxmpd) goto ddloop;
|
|
||||||
newlin();
|
|
||||||
mltplr>>;
|
|
||||||
maxmpd<<;
|
|
||||||
if (mltplr <> 0) goto drloop;
|
|
||||||
newlin();
|
|
||||||
prchr('D');
|
|
||||||
prchr('I');
|
|
||||||
prchr('V');
|
|
||||||
prchr(' ');
|
|
||||||
prchr('O');
|
|
||||||
prchr('K');
|
|
||||||
newlin();
|
|
||||||
|
|
||||||
|
|
||||||
tstrnd: //Test rand() and rands()
|
|
||||||
char countr, rndnum, rndtbl[255];
|
|
||||||
|
|
||||||
rands(1); //Seed Random Number Generator;
|
|
||||||
|
|
||||||
countr = 0;
|
|
||||||
|
|
||||||
riloop:
|
|
||||||
rndtbl[countr] = 0;
|
|
||||||
countr++;
|
|
||||||
if (countr <> 0) goto riloop;
|
|
||||||
|
|
||||||
rnloop:
|
|
||||||
rndnum = rand();
|
|
||||||
if (rndtbl[rndnum] > 0) goto rnderr;
|
|
||||||
rndtbl[rndnum] = $FF;
|
|
||||||
prbyte(rndnum);
|
|
||||||
prchr(' ');
|
|
||||||
countr++;
|
|
||||||
if (countr < 255) goto rnloop;
|
|
||||||
newlin();
|
|
||||||
prchr('R');
|
|
||||||
prchr('A');
|
|
||||||
prchr('N');
|
|
||||||
prchr('D');
|
|
||||||
prchr(' ');
|
|
||||||
prchr('O');
|
|
||||||
prchr('K');
|
|
||||||
newlin();
|
|
||||||
|
|
||||||
tstc2a: //Test ctoa();
|
|
||||||
char srcchr, dstchr, tststr[4];
|
|
||||||
|
|
||||||
srcchr = 0;
|
|
||||||
caloop:
|
|
||||||
prbyte(srcchr);
|
|
||||||
prchr(' ');
|
|
||||||
ctoa(srcchr, &tststr);
|
|
||||||
dstchr = atoc(&tststr);
|
|
||||||
if (srcchr <> dstchr) goto c2aerr;
|
|
||||||
srcchr++;
|
|
||||||
if (srcchr <> 0) goto caloop;
|
|
||||||
newlin();
|
|
||||||
prchr('C');
|
|
||||||
prchr('T');
|
|
||||||
prchr('O');
|
|
||||||
prchr('A');
|
|
||||||
prchr(' ');
|
|
||||||
prchr('O');
|
|
||||||
prchr('K');
|
|
||||||
newlin();
|
|
||||||
|
|
||||||
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
abserr:
|
|
||||||
prchr('A');
|
|
||||||
prchr('B');
|
|
||||||
prchr('S');
|
|
||||||
prchr('(');
|
|
||||||
prbyte(onum);
|
|
||||||
prchr(')');
|
|
||||||
prchr('=');
|
|
||||||
prbyte(anum);
|
|
||||||
prchr(',');
|
|
||||||
prbyte(cnum);
|
|
||||||
newlin();
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
merror:
|
|
||||||
newlin();
|
|
||||||
prbyte(mltplr);
|
|
||||||
prchr('*');
|
|
||||||
prbyte(mltpnd);
|
|
||||||
prchr('=');
|
|
||||||
//prbyte(ovrflw);
|
|
||||||
prbyte(prodct);
|
|
||||||
prchr(',');
|
|
||||||
//prbyte(acmmsb);
|
|
||||||
prbyte(acmlsb);
|
|
||||||
newlin();
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
derror:
|
|
||||||
newlin();
|
|
||||||
prbyte(divdnd);
|
|
||||||
prchr('/');
|
|
||||||
prbyte(divisr);
|
|
||||||
prchr('=');
|
|
||||||
prbyte(quotnt);
|
|
||||||
prchr(',');
|
|
||||||
prbyte(mltplr);
|
|
||||||
newlin();
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
rnderr:
|
|
||||||
prchr('R');
|
|
||||||
prchr('A');
|
|
||||||
prchr('N');
|
|
||||||
prchr('D');
|
|
||||||
prchr('(');
|
|
||||||
prchr(')');
|
|
||||||
prchr('=');
|
|
||||||
prbyte(rndnum);
|
|
||||||
prchr(',');
|
|
||||||
prbyte(countr);
|
|
||||||
newlin();
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
c2aerr:
|
|
||||||
prchr('C');
|
|
||||||
prchr('T');
|
|
||||||
prchr('O');
|
|
||||||
prchr('A');
|
|
||||||
prchr('(');
|
|
||||||
prbyte(srcchr);
|
|
||||||
prchr(')');
|
|
||||||
prchr('=');
|
|
||||||
prbyte(dstchr);
|
|
||||||
newlin();
|
|
||||||
goto exit;
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ ECHO Compiling File %1.c02 for VIC 20 +8k
|
||||||
..\c02.exe -h vic8k -s vic -s cbm %1 >%1.dbg
|
..\c02.exe -h vic8k -s vic -s cbm %1 >%1.dbg
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO EOF
|
IF %ERRORLEVEL% NEQ 0 GOTO EOF
|
||||||
ECHO Assembling File %1.asm
|
ECHO Assembling File %1.asm
|
||||||
C:\Programs\dasm %1.asm -f1 -o%1.prg -l%1.lst -s%1.sym
|
..\a02.exe -p %1.asm %1.prg %1.lst >%1.out
|
||||||
|
REM C:\Programs\dasm %1.asm -f1 -o%1.prg -l%1.lst -s%1.sym
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO EOF
|
IF %ERRORLEVEL% NEQ 0 GOTO EOF
|
||||||
|
|
||||||
ECHO Starting Emulator
|
ECHO Starting Emulator
|
||||||
|
|
272
test/xmemtest.c02
Normal file
272
test/xmemtest.c02
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
/**************************************
|
||||||
|
* TESTXMEM - Test Library xmemory.h02 *
|
||||||
|
**************************************/
|
||||||
|
|
||||||
|
//use -h option on command line
|
||||||
|
#include <screen.h02>
|
||||||
|
#include <stddef.h02>
|
||||||
|
#include <stdlib.h02>
|
||||||
|
#include <intlib.h02>
|
||||||
|
#include <stdio.h02>
|
||||||
|
#include <stdiox.h02>
|
||||||
|
#include <xmemory.h02>
|
||||||
|
|
||||||
|
char aa; //Function Arguments
|
||||||
|
|
||||||
|
alias char banked = $A000; //Beginning of Banked Memory
|
||||||
|
int icount;
|
||||||
|
|
||||||
|
char i; //Index Variable
|
||||||
|
char chrctr; //Get/Put Character
|
||||||
|
int intger; //Get/Put Integer
|
||||||
|
char r[255],w[255]; //Read/Write Arrays
|
||||||
|
|
||||||
|
char ibank, ipage, ibyte; //Index Bank, Page, and Byte
|
||||||
|
char lbank, lpage, lbyte; //Logical Bank, Page, and Byte
|
||||||
|
char mbank, mpage, mbyte; //Memory Bank, Page, and Byte
|
||||||
|
char pbank, ppage, pbyte; //Physical Bank, Page, and Byte
|
||||||
|
char sbank, spage, sbyte; //Starting Bank, Page, and Byte
|
||||||
|
char ebank, epage, ebyte; //Starting Bank, Page, and Byte
|
||||||
|
|
||||||
|
void passed() { putln("PASSED");}
|
||||||
|
|
||||||
|
void paddrs(aa) {
|
||||||
|
if (aa) newlin(); else puts(", ");
|
||||||
|
printf(setdst(xgetpa()),"PA=$%h%w, ");
|
||||||
|
printf(setdst(xgetla()),"LA=$%h%w ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void perror() {
|
||||||
|
printf(); //Implied Arguments
|
||||||
|
paddrs(#FALSE);
|
||||||
|
newlin();
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test xclcpa() and xclcla() */
|
||||||
|
void tstlpl(sbank,spage,sbank) {
|
||||||
|
ibank=sbank; ipage=spage; ibyte=sbyte;
|
||||||
|
while (ibank<=#XLBANK) {
|
||||||
|
putc('.');
|
||||||
|
while() {
|
||||||
|
while() {
|
||||||
|
//printf(setdst(ibank,ipage,ibyte),"%n ORIGINAL: $%h%w");
|
||||||
|
pbank,ppage,pbyte = xclcpa(ibank,ipage,ibyte);
|
||||||
|
//printf(setdst()," PHYSICAL: $%h%w");
|
||||||
|
lbank,lpage,lbyte = xclcla(pbank,ppage,pbyte);
|
||||||
|
//printf(setdst(),", LOGICAL: $%h%w");
|
||||||
|
if (lbank<>ibank or lpage<>ipage or ibyte<>lbyte)
|
||||||
|
perror(setdst(ibank,ipage,ibyte),"%nERROR IN BANK $%h ADDRESS $%w");
|
||||||
|
if (getkey()==#ESCKEY) goto exit;
|
||||||
|
ibyte=ibyte+$10; if (!ibyte) break;
|
||||||
|
} ipage++; if (!ipage) break;
|
||||||
|
} ibank++; if (!ibank) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test xgetla() and xsetla() */
|
||||||
|
void tstgsl(ibank,ipage,ibank) {
|
||||||
|
while (ibank<=#XLBANK) {
|
||||||
|
putc('.');
|
||||||
|
while() {
|
||||||
|
while() {
|
||||||
|
//printf(setdst(ibank,ipage,ibyte),"%n SET: $%h%w");
|
||||||
|
xsetla(ibank,ipage,ibyte);
|
||||||
|
lbank,lpage,lbyte = xgetla();
|
||||||
|
//printf(setdst(),", GOT: $%h%w");
|
||||||
|
if (lbank<>ibank or lpage<>ipage or ibyte<>lbyte)
|
||||||
|
perror(setdst(ibank,ipage,ibyte),"%nERROR IN BANK $%h ADDRESS $%w");
|
||||||
|
if (getkey()==#ESCKEY) goto exit;
|
||||||
|
ibyte=ibyte+$10; if (!ibyte) break;
|
||||||
|
} ipage++; if (!ipage) break;
|
||||||
|
} ibank++; if (!ibank) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test xincpa() */
|
||||||
|
void tstipa(ibank,ipage,ibank) {
|
||||||
|
xsetla(ibank,ipage,ibyte); //Set Logical Address to 0
|
||||||
|
while (ibank<=#XLBANK) {
|
||||||
|
putc('.');
|
||||||
|
while() {
|
||||||
|
//clrscr();
|
||||||
|
while() {
|
||||||
|
pbank,ppage,pbyte = xgetpa(ibank,ipage,ibyte);
|
||||||
|
//printf(setdst(),"$%h%w:");
|
||||||
|
lbank,lpage,lbyte = xgetla(); //Get Logical Address
|
||||||
|
//printf(setdst(),"$%h%w ");
|
||||||
|
if (lbank<>ibank or lpage<>ipage or ibyte<>lbyte)
|
||||||
|
perror(setdst(ibank,ipage,ibyte),"%nERROR IN BANK $%h ADDRESS $%w");
|
||||||
|
xincpa(); //Increment Physical Address
|
||||||
|
ibyte++; if (!ibyte) break;
|
||||||
|
} ipage++; if (!ipage) break;
|
||||||
|
if (getkey()==#ESCKEY) goto exit;
|
||||||
|
} ibank++; if (!ibank) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test xgetc() and xputc() */
|
||||||
|
void tstgpc(sbank,spage,sbyte) {
|
||||||
|
while() {
|
||||||
|
//printf(setdst(),"$%h%w");
|
||||||
|
putc('.');
|
||||||
|
ibank=sbank; ipage=spage; ibyte=sbyte;
|
||||||
|
xsetla(ibank,ipage,ibyte);
|
||||||
|
i=0; do { xputc(i); i++; } while (i);
|
||||||
|
xsetla(ibank,ipage,ibyte);
|
||||||
|
i=0; do {
|
||||||
|
if (xgetc()<>i) perror(setdst(xgetpa()),"%nERROR IN BANK $%h ADDRESS $%w");
|
||||||
|
i++;
|
||||||
|
} while (i);
|
||||||
|
sbank++;spage++;sbyte++;
|
||||||
|
if (!sbank or sbank>#XLBANK) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test xgeti() and xputi() */
|
||||||
|
void tstgpi(sbank,spage,sbyte) {
|
||||||
|
while() {
|
||||||
|
//*printf(setdst(),"$%h%w");
|
||||||
|
putc('.');
|
||||||
|
ibank=sbank; ipage=spage; ibyte=sbyte;
|
||||||
|
//Write 256 Integers
|
||||||
|
xsetla(ibank,ipage,ibyte);
|
||||||
|
i=0; do {
|
||||||
|
mpage=i;mbyte=i^$FF;
|
||||||
|
xputi(.,mpage,mbyte);
|
||||||
|
i++;
|
||||||
|
} while (i);
|
||||||
|
//Read 256 Integers
|
||||||
|
xsetla(ibank,ipage,ibyte);
|
||||||
|
i=0; do {
|
||||||
|
mpage=i;mbyte=i^$FF;
|
||||||
|
intger = xgeti();
|
||||||
|
if (<intger<>mbyte or >intger<>mpage)
|
||||||
|
perror(setdst(xgetpa()),"%nERROR IN BANK $%h ADDRESS $%w");
|
||||||
|
i++;
|
||||||
|
} while (i);
|
||||||
|
//Set Next Start Address
|
||||||
|
sbank++;spage++;sbyte++;
|
||||||
|
if (!sbank or sbank>#XLBANK) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test xgetl() and xputl() */
|
||||||
|
void tstgpl(sbank,spage,sbyte) {
|
||||||
|
while() {
|
||||||
|
//*printf(setdst(),"$%h%w");
|
||||||
|
putc('.');
|
||||||
|
ibank=sbank; ipage=spage; ibyte=sbyte;
|
||||||
|
//Write 256 Integers
|
||||||
|
xsetla(ibank,ipage,ibyte);
|
||||||
|
i=0; do {
|
||||||
|
mbyte=i; mpage=i^$FF; mbank = -i;
|
||||||
|
xputi(mbank,mpage,mbyte);
|
||||||
|
i++;
|
||||||
|
} while (i);
|
||||||
|
//Read 256 Integers
|
||||||
|
xsetla(ibank,ipage,ibyte);
|
||||||
|
i=0; do {
|
||||||
|
mbyte=i; mpage=i^$FF; mbank = -i;
|
||||||
|
intger = xgeti();
|
||||||
|
if (<intger<>mbyte or >intger<>mpage)
|
||||||
|
perror(setdst(xgetpa()),"%nERROR IN BANK $%h ADDRESS $%w");
|
||||||
|
i++;
|
||||||
|
} while (i);
|
||||||
|
//Set Next Start Address
|
||||||
|
sbank++;spage++;sbyte++;
|
||||||
|
if (!sbank or sbank>#XLBANK) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test xread() and xwrite() */
|
||||||
|
void tstxrw(sbank,spage,epage) {
|
||||||
|
i=0; do {w[i]=i;i++;} while (i); //Fill Write Array
|
||||||
|
ibank=sbank;
|
||||||
|
while (ibank<=#XLBANK) {
|
||||||
|
putc('.');
|
||||||
|
//Write 256,1-255 bytes of Array
|
||||||
|
ipage=spage; xsetla(ibank,0,ipage);
|
||||||
|
do {
|
||||||
|
//paddrs(#TRUE);
|
||||||
|
//inline $ff;
|
||||||
|
xwrite(ipage,&w);
|
||||||
|
//if (banked=61) perror("MEMORY OVERWRITE ERROR!");
|
||||||
|
ipage++;
|
||||||
|
} while (ipage<>epage);
|
||||||
|
//paddrs(#TRUE);
|
||||||
|
//Read 256,1-255 bytes of Array
|
||||||
|
ipage=spage; xsetla(ibank,0,ipage);
|
||||||
|
do {
|
||||||
|
//printf(ipage,"%n%h:");
|
||||||
|
//inline $ff;
|
||||||
|
//paddrs(#TRUE);
|
||||||
|
xread(ipage,&r);
|
||||||
|
i=0; do {
|
||||||
|
//printf(r[i],"%h."); printf(w[i],"%h,");
|
||||||
|
if (r[i]<>w[i]) perror(i,"ERROR IN INDEX %d");
|
||||||
|
i++;
|
||||||
|
} while(i<>ipage);
|
||||||
|
ipage++;
|
||||||
|
} while (ipage<>epage);
|
||||||
|
ibank++; if (!ibank) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test xload() and xsave() */
|
||||||
|
void tstxls(sbank,spage,sbyte) {
|
||||||
|
setsrc(&$F000); //Most Systems have ROM from $F000 to $FFFF
|
||||||
|
xsetla(sbank,spage,sbyte);
|
||||||
|
xsave(&$1000); //Save through $FFFF
|
||||||
|
setdst(&$8000); //There's usually free RAM here
|
||||||
|
xsetla(sbank,spage,sbyte);
|
||||||
|
xload(&$1000); //Load bytes saved from $F000 to $FFFF
|
||||||
|
srcptr = &$F000; dstptr = &$8000; icount = &$1000;
|
||||||
|
while (<icount or >icount) {
|
||||||
|
//putwrd(srcptr); putchr(':'); puthex(*srcptr); putspc();
|
||||||
|
//putwrd(dstptr); putchr(':'); puthex(*dstptr); putspc();
|
||||||
|
if (*srcptr <> *dstptr) perror("ERROR IN XLOAD() AND/OR XSAVE()\n");
|
||||||
|
if (!<icount) putc('.');
|
||||||
|
srcptr++; dstptr++; icount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main:
|
||||||
|
|
||||||
|
if (!#XLBANK) perror("Extended Memory Not Supported");
|
||||||
|
|
||||||
|
/*
|
||||||
|
puts("TESTING XCLCPA() AND XCLCLA()");
|
||||||
|
tstlpl($00,$00,$00);
|
||||||
|
passed();
|
||||||
|
|
||||||
|
//XGETPA() AND XSETPA() NOT DIRECTLY TESTED
|
||||||
|
//VALID VALUES ARE SYSTEM DEPENDENT
|
||||||
|
|
||||||
|
puts("TESTING XGETLA() AND XSETLA()");
|
||||||
|
tstgsl($00,$00,$00);
|
||||||
|
passed();
|
||||||
|
|
||||||
|
puts("TESTING XINCPA().............");
|
||||||
|
tstipa($00,$00,$00);
|
||||||
|
passed();
|
||||||
|
|
||||||
|
puts("TESTING XPUTC() AND XGETC()..");
|
||||||
|
tstgpc($00,$00,$00);
|
||||||
|
passed();
|
||||||
|
|
||||||
|
puts("TESTING XPUTI() AND XGETI()..");
|
||||||
|
tstgpi($00,$00,$00);
|
||||||
|
passed();
|
||||||
|
|
||||||
|
puts("TESTING XREAD() AND XWRITE().");
|
||||||
|
tstxrw($00,$00,$7F);
|
||||||
|
passed();
|
||||||
|
*/
|
||||||
|
|
||||||
|
puts("TESTING XLOAD() AND XSAVE().");
|
||||||
|
tstxls($00,$00,$00);
|
||||||
|
passed();
|
||||||
|
|
||||||
|
goto exit;
|
||||||
|
|
17
work/a02.bat
17
work/a02.bat
|
@ -1,3 +1,14 @@
|
||||||
@ECHO Assembling File %1.asm
|
@ECHO OFF
|
||||||
dasm %1.asm -f3 -o%1.bin -l%1.lst -s%1.sym
|
IF "%1" == "" (
|
||||||
|
ECHO Usage: %0 a02file
|
||||||
|
GOTO :EXIT
|
||||||
|
)
|
||||||
|
SET ASMEXT=""
|
||||||
|
IF EXIST %1.a02 SET ASMEXT=a02
|
||||||
|
IF EXIST %1.asm SET ASMEXT=asm
|
||||||
|
IF "%ASMEXT%" == "" (
|
||||||
|
ECHO Assembly File %1 Not Found
|
||||||
|
GOTO :EXIT
|
||||||
|
)
|
||||||
|
ECHO Assembling File %1.%ASMEXT%
|
||||||
|
..\a02.exe -d %1.%ASMEXT% %1.bin %1.lst >%1.out
|
||||||
|
|
18
work/a02inc.a02
Normal file
18
work/a02inc.a02
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
;A02 Assembler Test Include File
|
||||||
|
|
||||||
|
TRUE: EQU $FF
|
||||||
|
FALSE: .EQU $00
|
||||||
|
|
||||||
|
one equ 1
|
||||||
|
two .equ 1 + 1
|
||||||
|
three equ one + one + one
|
||||||
|
four .equ three + 1
|
||||||
|
|
||||||
|
|
||||||
|
PNTR: EQU $80
|
||||||
|
.local EQU 99
|
||||||
|
STRUCT EQU $0FFF
|
||||||
|
|
||||||
|
.END ;Return to Main File
|
||||||
|
|
||||||
|
IGNORE EQU $9999 ;This will Not be Assembled
|
103
work/a02test.a02
Normal file
103
work/a02test.a02
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
;A02 Assembler Test File
|
||||||
|
|
||||||
|
INCLUDE "a02inc.a02"
|
||||||
|
|
||||||
|
start ORG $0400 ;Start of Code
|
||||||
|
SUBROUTINE
|
||||||
|
flags: CLC
|
||||||
|
SEC
|
||||||
|
CLI
|
||||||
|
SEI
|
||||||
|
CLV
|
||||||
|
CLD
|
||||||
|
.local SED
|
||||||
|
SUBROUTINE
|
||||||
|
rgstr: DEX
|
||||||
|
DEY
|
||||||
|
INX
|
||||||
|
INY
|
||||||
|
TAX
|
||||||
|
TAY
|
||||||
|
TSX
|
||||||
|
TXA
|
||||||
|
TXS
|
||||||
|
TYA
|
||||||
|
SUBROUTINE
|
||||||
|
retrn: RTI
|
||||||
|
RTS
|
||||||
|
SUBROUTINE
|
||||||
|
stack: PHA
|
||||||
|
PHP
|
||||||
|
PHX
|
||||||
|
PHY
|
||||||
|
PLA
|
||||||
|
PLP
|
||||||
|
PLX
|
||||||
|
PLY
|
||||||
|
SUBROUTINE
|
||||||
|
other: NOP
|
||||||
|
BRK
|
||||||
|
SUBROUTINE
|
||||||
|
branch: BCC rgstr
|
||||||
|
BCS flags
|
||||||
|
.loop BEQ retrn
|
||||||
|
BNE jump
|
||||||
|
BMI .next
|
||||||
|
BPL .loop
|
||||||
|
BRA branch
|
||||||
|
.next BVC +127
|
||||||
|
BVS -128
|
||||||
|
SUBROUTINE
|
||||||
|
jump JMP .next
|
||||||
|
JMP (words )
|
||||||
|
JMP (pntr,x)
|
||||||
|
.next JSR retrn
|
||||||
|
SUBROUTINE
|
||||||
|
memory: ADC #$98 ;Immediate
|
||||||
|
AND TABLE,Y ;Absolute,Y
|
||||||
|
CMP PNTR,Y ;Absolute,Y (Zero Page Address)
|
||||||
|
EOR (PNTR,X) ;(Indirect,X)
|
||||||
|
LDA (PNTR),Y ;(Indirect),Y
|
||||||
|
ORA (PNTR) ;(Indirect)
|
||||||
|
ASL ;Accumulator
|
||||||
|
DEC PNTR ;ZeroPage
|
||||||
|
INC PNTR,X ;ZeroPage,X
|
||||||
|
LSR BYTES ;Absolute
|
||||||
|
ROL BYTES,X ;Absolute,X
|
||||||
|
ROR $ABCD,X ;Absolute,X
|
||||||
|
CPX #$76 ;Immediate
|
||||||
|
CPY PNTR ;ZeroPage
|
||||||
|
STY PNTR,X ;ZeroPage,X
|
||||||
|
STZ $CDEF ;Absolute
|
||||||
|
LDY $CDEF,X ;Absolute,X
|
||||||
|
TRB PNTR ;ZeroPage
|
||||||
|
TSB $1234 ;Absolute
|
||||||
|
SUBROUTINE
|
||||||
|
exprsn LDA #PNTR+1 ;Immediate
|
||||||
|
LDA PNTR+1 ;ZeroPage
|
||||||
|
LDA (PNTR+2) ;Indirect
|
||||||
|
LDA (PNTR+4,X) ;(Indirect,X)
|
||||||
|
LDA (PNTR+6),Y ;(Indirect),Y
|
||||||
|
LDA STRUCT ;Absolute
|
||||||
|
LDX #<STRUCT ;LSB Immediate
|
||||||
|
LDY #>STRUCT ;MSB Immediate
|
||||||
|
LDA STRUCT+1
|
||||||
|
LDX #<STRUCT+1
|
||||||
|
LDY #>STRUCT+1
|
||||||
|
LDA STRUCT+2
|
||||||
|
LDX #<(STRUCT+2)
|
||||||
|
LDY #>(STRUCT+2)
|
||||||
|
|
||||||
|
BYTES byte 99, %10101010,'~' ;Bytes
|
||||||
|
.byte $12,$34
|
||||||
|
HEXES hex 01,23,45,67,89 ;Hexadecimal
|
||||||
|
.hex ,AB,CD,EF,1A,2B,3C,D4,E5,F6
|
||||||
|
WORDS word $3456
|
||||||
|
Align 256
|
||||||
|
TABLE .word $1357,$9BDF,$2468
|
||||||
|
TEXT byte "ABCDEFGHIJKLMNOPQRSTUVWXYZ",0
|
||||||
|
|
||||||
|
END ;Nothing after this will be Assembled
|
||||||
|
STY (STRUCT),X ;Illegal Addressing Mode
|
||||||
|
DC.W ;Unsupported Pseudo-Op
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
@ECHO Compiling File %1.c02
|
@ECHO Compiling File %1.c02
|
||||||
..\c02.exe %1 >%1.dbg
|
..\c02.exe -c 65C02 %1 >%1.dbg
|
||||||
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
OP VALUE
|
|
||||||
= 1
|
|
||||||
< 2
|
|
||||||
<= 3
|
|
||||||
> 4
|
|
||||||
>= 5
|
|
||||||
<> 6
|
|
||||||
|
|
258
work/opcodes.a02
Normal file
258
work/opcodes.a02
Normal file
|
@ -0,0 +1,258 @@
|
||||||
|
PROCESSOR 6502
|
||||||
|
ORG $1000
|
||||||
|
X00 BRK ;00
|
||||||
|
X01 ORA ($10,X) ;01
|
||||||
|
X02 BYTE $02 ;NOP #IMD
|
||||||
|
X03 BYTE $03 ;NOP
|
||||||
|
X04 TSB $40 ;04
|
||||||
|
X05 ORA $50 ;05
|
||||||
|
X06 ASL $60 ;06
|
||||||
|
X07 RMB 0,$70 ;07
|
||||||
|
X08 PHP ;08
|
||||||
|
X09 ORA #$90 ;09
|
||||||
|
X0A ASL ;0A
|
||||||
|
X0B BYTE $0B ;NOP
|
||||||
|
X0C TSB $CBA9 ;0C
|
||||||
|
X0D ORA $DCBA ;0D
|
||||||
|
X0E ASL $EDCB ;0E
|
||||||
|
X0F BBR0 $F0,X00 ;0F
|
||||||
|
X10 BPL X11 ;10
|
||||||
|
X11 ORA ($11),Y ;11
|
||||||
|
X12 BYTE $12 ;NOP #IMD
|
||||||
|
X13 BYTE $13 ;NOP
|
||||||
|
X14 TRB $51 ;14
|
||||||
|
X15 ORA $61,X ;15
|
||||||
|
X16 ASL $71,X ;16
|
||||||
|
X17 RMB1 $71 ;17
|
||||||
|
X18 CLC ;18
|
||||||
|
X19 ORA $A987,Y ;19
|
||||||
|
X1A BYTE $1A ;1A
|
||||||
|
X1B BYTE $1B ;1A
|
||||||
|
X1C TRB $CBA9 ;1C
|
||||||
|
X1D ORA $DCBA,X ;1D
|
||||||
|
X1E ASL $EDCB,X ;1E
|
||||||
|
X1F BBR 1,$F1,X11 ;1F
|
||||||
|
X20 JSR $0123 ;20
|
||||||
|
X21 AND ($12,X) ;21
|
||||||
|
X22 BYTE $22 ;NOP #IMD
|
||||||
|
X23 BYTE $23 ;NOP
|
||||||
|
X24 BIT $42 ;24
|
||||||
|
X25 AND $52 ;25
|
||||||
|
X26 ROL $62 ;26
|
||||||
|
X27 RMB 2,$72 ;27
|
||||||
|
X28 PLP ;28
|
||||||
|
X29 AND #$92 ;29
|
||||||
|
X2A ROL ;2A
|
||||||
|
X2B BYTE $2B ;2B
|
||||||
|
X2C BIT $CBDA ;2C
|
||||||
|
X2D AND $DCBA ;2D
|
||||||
|
X2E ROL $EDCB ;2E
|
||||||
|
X2F BBR2 $F2,X22 ;2F
|
||||||
|
X30 BMI X33 ;30
|
||||||
|
X31 AND ($13),Y ;31
|
||||||
|
X32 BYTE $32 ;NOP #IMD
|
||||||
|
X33 BYTE $33 ;NOP
|
||||||
|
X34 BIT $43,X ;34
|
||||||
|
X35 AND $53,X ;35
|
||||||
|
X36 ROL $63,X ;36
|
||||||
|
X37 RMB3 $73 ;37
|
||||||
|
X38 SEC ;38
|
||||||
|
X39 AND $9876,Y ;39
|
||||||
|
X3A DEC ;3A
|
||||||
|
X3B BYTE $3B ;NOP
|
||||||
|
X3C BIT $CBA9,X ;3C
|
||||||
|
X3D AND $DCBA,X ;3D
|
||||||
|
X3E ROL $EDCB,X ;3E
|
||||||
|
X3F BBR 3,$F3,X33 ;3F
|
||||||
|
X40 RTI ;40
|
||||||
|
X41 EOR ($14,X) ;41
|
||||||
|
X42 BYTE $42 ;NOP #IMD
|
||||||
|
X43 BYTE $43 ;NOP
|
||||||
|
X44 BYTE $44 ;NOP $ZP
|
||||||
|
X45 EOR $54 ;45
|
||||||
|
X46 LSR $64 ;46
|
||||||
|
X47 RMB 4,$74 ;47
|
||||||
|
X48 PHA ;48
|
||||||
|
X49 EOR #$94 ;49
|
||||||
|
X4A LSR ;4A
|
||||||
|
X4B BYTE $4B ;NOP
|
||||||
|
X4C JMP $CBA9 ;4C
|
||||||
|
X4D EOR $DCBA ;4D
|
||||||
|
X4E LSR $EDCB ;4E
|
||||||
|
X4F BBR4 $F4,X44 ;4F
|
||||||
|
X50 BVC X55 ;50
|
||||||
|
X51 EOR ($15),Y ;51
|
||||||
|
X52 EOR ($25) ;52
|
||||||
|
X53 BYTE $53 ;NOP
|
||||||
|
X54 BYTE $54 ;NOP $ZP
|
||||||
|
X55 EOR $55,X ;55
|
||||||
|
X56 LSR $65,X ;56
|
||||||
|
X57 RMB5 $75 ;57
|
||||||
|
X58 CLI ;58
|
||||||
|
X59 EOR $9876,Y ;59
|
||||||
|
X5A PHY ;5A
|
||||||
|
X5B BYTE $5B ;NOP
|
||||||
|
X5C BYTE $5C ;NOP $ABSL
|
||||||
|
X5D EOR $CBA9,X ;5C
|
||||||
|
X5E LSR $DCBA,X ;5E
|
||||||
|
X5F BBR 5,$F5,X55 ;5F
|
||||||
|
X60 RTS ;60
|
||||||
|
X61 ADC ($16,X) ;61
|
||||||
|
X62 BYTE $62 ;NOP #IMD
|
||||||
|
X63 BYTE $63 ;NOP
|
||||||
|
X64 STZ $46 ;64
|
||||||
|
X65 ADC $56 ;65
|
||||||
|
X66 ROR $66 ;66
|
||||||
|
X67 RMB 6,$76 ;67
|
||||||
|
X68 PLA ;68
|
||||||
|
X69 ADC #$96 ;69
|
||||||
|
X6A ROR ;6A
|
||||||
|
X6B BYTE $6B ;NOP
|
||||||
|
X6C JMP ($CDBA) ;6C
|
||||||
|
X6D ADC $DCBA ;6D
|
||||||
|
X6E ROR $EDCB ;6E
|
||||||
|
X6F BBR6 $F6,X66 ;6F
|
||||||
|
X70 BVS X77 ;70
|
||||||
|
X71 ADC ($17),Y ;71
|
||||||
|
X72 ADC ($27) ;72
|
||||||
|
X73 BYTE $73 ;NOP
|
||||||
|
X74 STZ $47,X ;74
|
||||||
|
X75 ADC $57,X ;75
|
||||||
|
X76 ROR $67,X ;76
|
||||||
|
X77 RMB7 $77 ;77
|
||||||
|
X78 SEI ;78
|
||||||
|
X79 ADC $9875,Y ;79
|
||||||
|
X7A PLY ;7A
|
||||||
|
X7B BYTE $7B ;NOP
|
||||||
|
X7C JMP ($C7,X) ;7C
|
||||||
|
X7D ADC $DCBA,X ;7E
|
||||||
|
X7E ROR $DCBA,X ;7E
|
||||||
|
X7F BBR 7,$F1,X77 ;7F
|
||||||
|
X80 BRA X88 ;80
|
||||||
|
X81 STA ($18,X) ;81
|
||||||
|
X82 BYTE $82 ;NOP #IMD
|
||||||
|
X83 BYTE $83 ;NOP
|
||||||
|
X84 STY $48 ;84
|
||||||
|
X85 STA $58 ;85
|
||||||
|
X86 STX $68 ;86
|
||||||
|
X87 SMB0 $78 ;87
|
||||||
|
X88 DEY ;88
|
||||||
|
X89 BIT #$98 ;89
|
||||||
|
X8A TXA ;8A
|
||||||
|
X8B BYTE $8B ;NOP
|
||||||
|
X8C STY $CBA9 ;8C
|
||||||
|
X8D STA $DCBA ;8D
|
||||||
|
X8E STX $EDCB ;8E
|
||||||
|
X8F BBS 0,$F8,X88 ;8F
|
||||||
|
X90 BCC X99 ;90
|
||||||
|
X91 STA ($19),Y ;91
|
||||||
|
X92 STA ($29) ;92
|
||||||
|
X93 BYTE $93 ;NOP
|
||||||
|
X94 STY $49,X ;94
|
||||||
|
X95 STA $59,X ;95
|
||||||
|
X96 STX $69,Y ;96
|
||||||
|
X97 SMB1 $79 ;97
|
||||||
|
X98 TYA ;98
|
||||||
|
X99 STA $9876,Y ;99
|
||||||
|
X9A TXS ;9A
|
||||||
|
X9B BYTE $9B ;NOP
|
||||||
|
X9C STZ $CBA9 ;9C
|
||||||
|
X9D STA $DCBA,X ;90
|
||||||
|
X9E STZ $EDCB,X ;9E
|
||||||
|
X9F BBS1 $F9,X99 ;8F
|
||||||
|
XA0 LDY #$0A ;A0
|
||||||
|
XA1 LDA ($1A,X) ;A1
|
||||||
|
XA2 LDX #$2A ;A2
|
||||||
|
XA3 BYTE $A3 ;NOP
|
||||||
|
XA4 LDY $4A ;A4
|
||||||
|
XA5 LDA $5A ;A5
|
||||||
|
XA6 LDX $6A ;A6
|
||||||
|
XA7 SMB1 $7A ;A7
|
||||||
|
XA8 TAY ;A8
|
||||||
|
XA9 LDA #$9A ;A9
|
||||||
|
XAA TAX ;AA
|
||||||
|
XAB BYTE $AB ;NOP
|
||||||
|
XAC LDY $CBA9 ;AC
|
||||||
|
XAD LDA $DCBA ;AD
|
||||||
|
XAE LDX $EDCB ;AE
|
||||||
|
XAF BBS 2,$FA,XAA ;AF
|
||||||
|
XB0 BCS XBB ;B0
|
||||||
|
XB1 LDA ($1B),Y ;B1
|
||||||
|
XB2 LDA ($2B) ;B2
|
||||||
|
XB3 BYTE $B3 ;NOP
|
||||||
|
XB4 LDY $B4,X ;B4
|
||||||
|
XB5 LDA $B5,X ;BS
|
||||||
|
XB6 LDX $B6,Y ;B6
|
||||||
|
XB7 SMB3 $7B ;B7
|
||||||
|
XB8 CLV ;B8
|
||||||
|
XB9 LDA $9876,Y ;B9
|
||||||
|
XBA TSX ;BA
|
||||||
|
XBB BYTE $BB ;NOP
|
||||||
|
XBC STX $CBA9,Y ;BC
|
||||||
|
XBD LDA $DCBA,X ;BD
|
||||||
|
XBE LDX $EDCB,Y ;BE
|
||||||
|
XBF BBS3 $FB,XBB ;BF
|
||||||
|
XC0 CPY #$0C ;C0
|
||||||
|
XC1 CMP ($1C,X) ;C1
|
||||||
|
XC2 BYTE $C2 ;NOP #imd
|
||||||
|
XC3 BYTE $C3 ;NOP
|
||||||
|
XC4 CPY $4C ;C4
|
||||||
|
XC5 CMP $5C ;C5
|
||||||
|
XC6 DEC $6C ;C6
|
||||||
|
XC7 SMB4 $7C ;C7
|
||||||
|
XC8 INY ;C8
|
||||||
|
XC9 CMP #$9C ;C9
|
||||||
|
XCA DEX ;CA
|
||||||
|
XCB WAI ;CB
|
||||||
|
XCC CPY $CBA9 ;CC
|
||||||
|
XCD CMP $DCBA ;CD
|
||||||
|
XCE DEC $EDCB ;CE
|
||||||
|
XCF BBS 4,$FC,XCC ;8F
|
||||||
|
XD0 BNE XDD ;D0
|
||||||
|
XD1 CMP ($1D),Y ;D1
|
||||||
|
XD2 CMP ($2D) ;D2
|
||||||
|
XD3 BYTE $D3 ;NOP
|
||||||
|
XD4 BYTE $D4 ;NOP $ZP,X
|
||||||
|
XD5 CMP $5D,X ;D5
|
||||||
|
XD6 DEC $6D,X ;D6
|
||||||
|
XD7 SMB5 $7D ;D7
|
||||||
|
XD8 CLD ;D8
|
||||||
|
XD9 CMP $9876,Y ;D9
|
||||||
|
XDA PHX ;DA
|
||||||
|
XDB STP ;DB
|
||||||
|
XDC BYTE $DC ;NOP $ABSL
|
||||||
|
XDD CMP $DCBA,X ;DD
|
||||||
|
XDE DEC $EDCB,X ;DE
|
||||||
|
XDF BBS5 $FD,XDD ;8F
|
||||||
|
XE0 CPX #$0E ;E0
|
||||||
|
XE1 SBC ($1E,X) ;E1
|
||||||
|
XE2 BYTE $E2 ;NOP #IMD
|
||||||
|
XE3 BYTE $E3 ;NOP
|
||||||
|
XE4 CPX $4E ;E4
|
||||||
|
XE5 SBC $5E ;E5
|
||||||
|
XE6 INC $6E ;E6
|
||||||
|
XE7 SMB6 $7E ;E7
|
||||||
|
XE8 INX ;E8
|
||||||
|
XE9 SBC #$9E ;E9
|
||||||
|
XEA NOP ;EA
|
||||||
|
XEB BYTE $EB ;NOP
|
||||||
|
XEC CPX $CBA9 ;EC
|
||||||
|
XED SBC $DCBA ;ED
|
||||||
|
XEE INC $EDCB ;EE
|
||||||
|
XEF BBS 6,$FE,XEE ;8F
|
||||||
|
XF0 BEQ XFF ;F0
|
||||||
|
XF1 SBC ($1F),Y ;F1
|
||||||
|
XF2 SBC ($2F) ;F2
|
||||||
|
XF3 BYTE $F3 ;NOP
|
||||||
|
XF4 BYTE $F4 ;NOP $ZP,X
|
||||||
|
XF5 SBC $5F,X ;F5
|
||||||
|
XF6 INC $6F,X ;F6
|
||||||
|
XF7 SMB7 $7F ;F7
|
||||||
|
XF8 SED ;F8
|
||||||
|
XF9 SBC $9876,Y ;F9
|
||||||
|
XFA PLX ;FA
|
||||||
|
XFB BYTE $FB ;NOP
|
||||||
|
XFC BYTE $FC ;NOP $ABSL
|
||||||
|
XFD SBC $DCBA,X ;FD
|
||||||
|
XFE INC $EDCB,X ;FE
|
||||||
|
XFF BBS7 $FF,XFF ;8F
|
Loading…
Reference in New Issue
Block a user