Compare commits
64 Commits
orcac-220b
...
master
Author | SHA1 | Date |
---|---|---|
Stephen Heumann | 69320cd4d8 | |
Stephen Heumann | 8278f7865a | |
Stephen Heumann | 6b7414384f | |
Stephen Heumann | 77e0b8fc59 | |
Stephen Heumann | 50636bd28b | |
Stephen Heumann | 83537fd3c7 | |
Stephen Heumann | 81934109fc | |
Stephen Heumann | 72234a4f2b | |
Stephen Heumann | 36f766a662 | |
Stephen Heumann | 4c402fc883 | |
Stephen Heumann | ca0147507b | |
Stephen Heumann | 24c6e72a83 | |
Stephen Heumann | 0f18fa63b5 | |
Stephen Heumann | 8f07ca5d6c | |
Stephen Heumann | 60b472a99e | |
Stephen Heumann | 995885540b | |
Stephen Heumann | 34c5be5cab | |
Stephen Heumann | 75a928e273 | |
Stephen Heumann | a545685ab4 | |
Stephen Heumann | ce94f4e2b6 | |
Stephen Heumann | 84fdb5c975 | |
Stephen Heumann | d1847d40be | |
Stephen Heumann | c671bb71a5 | |
Stephen Heumann | a646a03b5e | |
Stephen Heumann | 7ca30d7784 | |
Stephen Heumann | c9dc566c10 | |
Stephen Heumann | 2ca4aba5c4 | |
ksherlock | d7cc9b5909 | |
Kelvin Sherlock | 586229e6eb | |
Stephen Heumann | 0aee669746 | |
Stephen Heumann | 25085f5b81 | |
Stephen Heumann | 6905d8dced | |
Stephen Heumann | f815c1bda6 | |
Stephen Heumann | 5316b438d5 | |
Stephen Heumann | 4d8eaf93bc | |
Stephen Heumann | 7e5023844a | |
Stephen Heumann | 1aa654628a | |
Stephen Heumann | 9a56a50f5f | |
Stephen Heumann | adcab004df | |
Stephen Heumann | 7188b4f418 | |
Stephen Heumann | af3c8e1eea | |
Stephen Heumann | 0021fd81bc | |
Stephen Heumann | 966da239ee | |
Stephen Heumann | 5b294721f2 | |
Stephen Heumann | 914e5972bd | |
Stephen Heumann | 79e83c3092 | |
Stephen Heumann | e5c69670cd | |
Stephen Heumann | 509f09253f | |
Stephen Heumann | 05c9ea16c8 | |
Stephen Heumann | 661c9c440d | |
Stephen Heumann | c8517eff87 | |
Stephen Heumann | c2262929e9 | |
Stephen Heumann | 9d5360e844 | |
Stephen Heumann | 338bfdd908 | |
Stephen Heumann | 118e326ac9 | |
Stephen Heumann | 938fa96503 | |
Stephen Heumann | 986fe9a65b | |
Stephen Heumann | ab975b611c | |
Stephen Heumann | e123339a45 | |
Stephen Heumann | 0274b0ba83 | |
Stephen Heumann | 84401b4e97 | |
Stephen Heumann | 3a298ec341 | |
Stephen Heumann | 2974c1b4bb | |
Stephen Heumann | 9dad2b6186 |
|
@ -0,0 +1,44 @@
|
|||
Welcome to ORCA/C 2.2.1! This is a release containing updates from
|
||||
community members (Stephen Heumann and Kelvin Sherlock).
|
||||
|
||||
ORCA/C 2.2 adds support for almost all of the new language and library
|
||||
features required by the C17 standard. It also has several other new
|
||||
features, such as additional lint checks to help identify bugs and
|
||||
portability problems. In addition to these new features, ORCA/C 2.2
|
||||
includes hundreds of bug fixes in the compiler and libraries.
|
||||
|
||||
ORCA/C 2.2.1 includes additional bug fixes to ORCA/C 2.2.0.
|
||||
|
||||
The ORCA/C manual has been fully updated to cover ORCA/C 2.2, so new
|
||||
users should simply refer to that. Users familiar with older versions
|
||||
of ORCA/C can refer to the cc.notes file in the Release.Notes directory
|
||||
for a description of the changes between ORCA/C 2.0 and ORCA/C 2.2.1.
|
||||
|
||||
ORCA/C 2.2.1 requires a real or emulated Apple IIGS with at least the
|
||||
following specifications:
|
||||
|
||||
* 2 MB of RAM (3 MB or more recommended)
|
||||
* a hard drive or SSD
|
||||
* System 6.0.1 or later
|
||||
|
||||
ORCA/C can also be run on modern Mac, Windows, or Linux systems as a
|
||||
cross compiler by using Golden Gate, a specialized emulation tool by
|
||||
Kelvin Sherlock. It is available separately from Juiced.GS:
|
||||
https://juiced.gs/store/golden-gate/
|
||||
|
||||
If you have any questions, or if you want to get involved in ORCA/C
|
||||
development, please get in touch. The ORCA/C development project is
|
||||
hosted on GitHub, and bug reports or patches can be submitted there:
|
||||
https://github.com/byteworksinc/ORCA-C
|
||||
|
||||
Thanks to:
|
||||
* Mike Westerfield, for writing ORCA/C, releasing the source code,
|
||||
and permitting it to be updated by the community.
|
||||
* Kelvin Sherlock, for providing several patches and bug reports, and
|
||||
for writing several useful tools for modern Apple II development.
|
||||
* Soenke Behrens, for compiling a list of ORCA/C bug reports and test
|
||||
cases, which has helped me to identify and fix a number of bugs.
|
||||
* The developers of Csmith (http://embed.cs.utah.edu/csmith/), an
|
||||
automated compiler testing tool that has helped to find several bugs.
|
||||
|
||||
--Stephen Heumann (stephenheumann@gmail.com)
|
|
@ -0,0 +1,46 @@
|
|||
/***************************************************************
|
||||
*
|
||||
* Fibonacci
|
||||
*
|
||||
* Recursively computes Fibonacci numbers to test the speed of
|
||||
* function calls.
|
||||
*
|
||||
* To get the best performance from the desktop development
|
||||
* environment, be sure and turn debugging off from the
|
||||
* Compile Dialog. Use the Compile command from the Run menu
|
||||
* to get the compile dialog.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
#pragma keep "FIB"
|
||||
#pragma optimize -1
|
||||
#pragma lint -1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define NTIMES 10 /* # iterations */
|
||||
#define NUMBER 23 /* largest Fib # smaller than 32767 */
|
||||
|
||||
|
||||
int Fibonacci(int x)
|
||||
|
||||
{
|
||||
if (x > 2)
|
||||
return Fibonacci(x-1)+Fibonacci(x-2);
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int main (void)
|
||||
|
||||
{
|
||||
int value;
|
||||
unsigned i;
|
||||
|
||||
printf("%d iterations:\n", NTIMES);
|
||||
for (i = 0; i < NTIMES; ++i)
|
||||
value = Fibonacci(NUMBER);
|
||||
printf("Fibonacci(%d) = %d\n", NUMBER, value);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/***************************************************************
|
||||
*
|
||||
* Float
|
||||
*
|
||||
* Test simple floating point operations.
|
||||
*
|
||||
* To get the best performance from the desktop development
|
||||
* environment, be sure and turn debugging off from the
|
||||
* Compile Dialog. Use the Compile command from the Run menu
|
||||
* to get the compile dialog.
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
#pragma keep "Float"
|
||||
#pragma optimize -1
|
||||
#pragma lint -1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define const1 3.141597
|
||||
#define const2 1.7839032e4
|
||||
#define count 1000
|
||||
|
||||
int main(void)
|
||||
|
||||
{
|
||||
double a,b,c;
|
||||
int i;
|
||||
|
||||
a = const1;
|
||||
b = const2;
|
||||
printf("%d iterations.\n", count);
|
||||
for (i = 0; i < count; ++i) {
|
||||
c = a*b;
|
||||
c = c/a;
|
||||
c = a*b;
|
||||
c = c/a;
|
||||
c = a*b;
|
||||
c = c/a;
|
||||
c = a*b;
|
||||
c = c/a;
|
||||
c = a*b;
|
||||
c = c/a;
|
||||
c = a*b;
|
||||
c = c/a;
|
||||
c = a*b;
|
||||
c = c/a;
|
||||
}
|
||||
printf("Done. C is %e.\n", c);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/***************************************************************
|
||||
*
|
||||
* Gamm
|
||||
*
|
||||
* Test the speed of floating point operations in a mix tha
|
||||
* is typical of scientific and engineering applications.
|
||||
*
|
||||
* To get the best performance from the desktop development
|
||||
* environment, be sure and turn debugging off from the
|
||||
* Compile Dialog. Use the Compile command from the Run menu
|
||||
* to get the compile dialog.
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
#pragma keep "Gamm"
|
||||
#pragma optimize -1
|
||||
#pragma lint -1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
int main (void)
|
||||
|
||||
{
|
||||
int five,i,j,n,rep,ten,thirty;
|
||||
float acc,acc1,divn,rn,root,x,y;
|
||||
float a[30], b[30], c[30];
|
||||
|
||||
printf("Start timing 15000 Gamm units\n");
|
||||
n = 50;
|
||||
five = 5;
|
||||
ten = 10;
|
||||
thirty = 30;
|
||||
rn = n;
|
||||
divn = 1.0/rn;
|
||||
x = 0.1;
|
||||
acc = 0.0;
|
||||
|
||||
/* initialize a and b */
|
||||
y = 1.0;
|
||||
for (i = 0; i < thirty; ++i) {
|
||||
a[i] = i+1;
|
||||
b[i] = -y;
|
||||
y = -y;
|
||||
};
|
||||
|
||||
/* one pass thru this loop corresponds to 300 gamm units */
|
||||
for (rep = 0; rep < n; ++rep) {
|
||||
/* first addition/subtraction loop */
|
||||
i = 29;
|
||||
for (j = 0; j < 30; ++j) {
|
||||
c[i] = a[i]+b[i];
|
||||
--i;
|
||||
};
|
||||
/* first polynomial loop */
|
||||
y = 1.0;
|
||||
for (i = 0; i < 10; ++i)
|
||||
y = (y+c[i])*x;
|
||||
acc1 = y*divn;
|
||||
/* first maximum element loop */
|
||||
y = c[10];
|
||||
for (i = 10; i < 20; ++i)
|
||||
if (c[i] > y)
|
||||
y = c[i];
|
||||
/* first square root loop */
|
||||
root = 1.0;
|
||||
for (i = 0; i < 5; ++i)
|
||||
root = 0.5*(root+y/root);
|
||||
acc1 = acc1+root*divn;
|
||||
/* second addition/subtraction loop */
|
||||
for (i = 0; i < 30; ++i)
|
||||
a[i] = c[i]-b[i];
|
||||
/* second polynomial loop */
|
||||
y = 0.0;
|
||||
for (i = 0; i < 10; ++i)
|
||||
y = (y+a[i])*x;
|
||||
/* second square root loop */
|
||||
root = 1.0;
|
||||
for (i = 1; i < 5; ++i)
|
||||
root = 0.5*(root+y/root);
|
||||
acc1 = acc1+root*divn;
|
||||
/* first multiplication loop */
|
||||
for (i = 0; i < thirty; ++i)
|
||||
c[i] = c[i]*b[i];
|
||||
/* second maximum element loop */
|
||||
y = c[19];
|
||||
for (i = 20; i < thirty; ++i)
|
||||
if (c[i] > y)
|
||||
y = c[i];
|
||||
/* third square root loop */
|
||||
root = 1.0;
|
||||
for (i = 0; i < 5; ++i)
|
||||
root = 0.5*(root+y/root);
|
||||
acc1 = acc1+root*divn;
|
||||
/* third polynomial loop */
|
||||
y = 0.0;
|
||||
for (i = 0; i < 10; ++i)
|
||||
y = (y+c[i])*x;
|
||||
acc1 = acc1+y*divn;
|
||||
/* third maximum element loop */
|
||||
y = c[0];
|
||||
for (i = 1; i < 10; ++i);
|
||||
if (c[i] > y)
|
||||
y = c[i];
|
||||
/* fourth square root loop */
|
||||
root = 1.0;
|
||||
for (i = 0; i < 5; ++i)
|
||||
root = 0.5*(root+y/root);
|
||||
acc1 = acc1+root*divn;
|
||||
acc = acc+acc1;
|
||||
}
|
||||
printf("%12d %12.7e %12.7e\n", n, acc, acc1);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/***************************************************************
|
||||
*
|
||||
* Integer Math
|
||||
*
|
||||
* Test the speed of the four basic integer math operations.
|
||||
*
|
||||
* To get the best performance from the desktop development
|
||||
* environment, be sure and turn debugging off from the
|
||||
* Compile Dialog. Use the Compile command from the Run menu
|
||||
* to get the compile dialog.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
#pragma keep "IMath"
|
||||
#pragma optimize -1
|
||||
#pragma lint -1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define ITER 10000
|
||||
|
||||
|
||||
int main (void)
|
||||
|
||||
{
|
||||
int a,b,c,d,e,f;
|
||||
unsigned i;
|
||||
|
||||
printf("Start timing...\n");
|
||||
b = 1000;
|
||||
c = 10;
|
||||
d = 100;
|
||||
e = 5;
|
||||
f = 10;
|
||||
for (i = 0; i < ITER; ++i) {
|
||||
a = b+c-d*e/f;
|
||||
a = b+c-d*e/f;
|
||||
a = b+c-d*e/f;
|
||||
a = b+c-d*e/f;
|
||||
a = b+c-d*e/f;
|
||||
a = b+c-d*e/f;
|
||||
a = b+c-d*e/f;
|
||||
a = b+c-d*e/f;
|
||||
a = b+c-d*e/f;
|
||||
a = b+c-d*e/f;
|
||||
a = b+c-d*e/f;
|
||||
}
|
||||
if (a == 960) {
|
||||
printf("Stop timing - correct result.\n");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
printf("INCORRECT RESULT.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/***************************************************************
|
||||
*
|
||||
* This is probably the most famous benchmark in use today.
|
||||
* It tests the speed that a compiler can do logic and looping
|
||||
* operations. While there are things that you can do to make
|
||||
* this benchmark run faster under ORCA/C, we have not
|
||||
* doctored it in any way - this is the original benchmark
|
||||
* in its original form.
|
||||
*
|
||||
* To get the best performance from the desktop development
|
||||
* environment, be sure and turn debugging off from the
|
||||
* Compile Dialog. Use the Compile command from the Run menu
|
||||
* to get the compile dialog.
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
#pragma keep "Prime"
|
||||
#pragma optimize -1
|
||||
#pragma lint -1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
#define size 8190
|
||||
|
||||
char flags[size+1];
|
||||
|
||||
void main (void)
|
||||
|
||||
{
|
||||
int i,prime,k,count,iter;
|
||||
|
||||
printf("10 iterations\n");
|
||||
for (iter = 1; iter <= 10; iter++) {
|
||||
count = 0;
|
||||
for (i = 0; i <= size; i++)
|
||||
flags[i] = true;
|
||||
for (i = 0; i <= size; i++) {
|
||||
if (flags[i]) {
|
||||
prime = i+i+3;
|
||||
/* printf("\n%d", prime); */
|
||||
for (k = i+prime; k <= size; k += prime)
|
||||
flags[k] = false;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\n%d primes.", count);
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/***************************************************************
|
||||
*
|
||||
* QuickSort
|
||||
*
|
||||
* Creates an array of long integers, then sorts the array.
|
||||
*
|
||||
* To get the best performance from the desktop development
|
||||
* environment, be sure and turn debugging off from the
|
||||
* Compile Dialog. Use the Compile command from the Run menu
|
||||
* to get the compile dialog.
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
#pragma keep "Quick"
|
||||
#pragma optimize -1
|
||||
#pragma lint -1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define maxNum 999 /* size of array to sort - 1 */
|
||||
#define count 10 /* # of iterations */
|
||||
#define modulus 0x00020000 /* for random number generator */
|
||||
#define c 13849
|
||||
#define a 25173
|
||||
|
||||
typedef long arrayType[maxNum];
|
||||
|
||||
arrayType buffer; /* array to sort */
|
||||
long seed; /* seed for random number generator */
|
||||
|
||||
|
||||
void Quick (int lo, int hi, arrayType base)
|
||||
|
||||
{
|
||||
int i,j;
|
||||
long pivot,temp;
|
||||
|
||||
if (hi > lo) {
|
||||
pivot = base[hi];
|
||||
i = lo-1;
|
||||
j = hi;
|
||||
do {
|
||||
do ++i; while ((base[i] < pivot) && (j > i));
|
||||
if (j > i)
|
||||
do --j; while ((base[j] > pivot) && (j > i));
|
||||
temp = base[i];
|
||||
base[i] = base[j];
|
||||
base[j] = temp;
|
||||
}
|
||||
while (j > i);
|
||||
base[j] = base[i];
|
||||
base[i] = base[hi];
|
||||
base[hi] = temp;
|
||||
Quick(lo, i-1, base);
|
||||
Quick(i+1, hi, base);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
long Random (long size)
|
||||
|
||||
{
|
||||
seed = seed*a+c;
|
||||
return seed % size;
|
||||
}
|
||||
|
||||
|
||||
int main (void)
|
||||
|
||||
{
|
||||
int i,j; /* loop variables */
|
||||
int pass; /* for checking the array */
|
||||
|
||||
seed = 7;
|
||||
printf("Filling array and sorting %d times.\n", count);
|
||||
for (i = 0; i < count; ++i) {
|
||||
for (j = 0; j < maxNum; ++j)
|
||||
buffer[j] = labs(Random(modulus));
|
||||
Quick(0, maxNum-1, buffer);
|
||||
}
|
||||
printf("Done.\n");
|
||||
|
||||
pass = 1;
|
||||
for (i = 0; i < maxNum-1; ++i)
|
||||
if (buffer[i] > buffer[i+1])
|
||||
pass = 0;
|
||||
if (pass) {
|
||||
printf("The last array is sorted properly.\n");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
printf("The last array is NOT sorted properly!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/***************************************************************
|
||||
*
|
||||
* Savage
|
||||
*
|
||||
* Test the speed (and stability) of floating point functions.
|
||||
*
|
||||
* To get the best performance from the desktop development
|
||||
* environment, be sure and turn debugging off from the
|
||||
* Compile Dialog. Use the Compile command from the Run menu
|
||||
* to get the compile dialog.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
#pragma keep "Savage"
|
||||
#pragma optimize -1
|
||||
#pragma lint -1
|
||||
|
||||
#define loop 250
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
int main (void)
|
||||
|
||||
{
|
||||
int i;
|
||||
double sum;
|
||||
|
||||
printf("Start...\n");
|
||||
sum = 1.0;
|
||||
for (i = 1; i < loop; ++i)
|
||||
sum = tan(atan(exp(log(sqrt(sum*sum)))))+1.0;
|
||||
printf("sum = %e", sum);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,288 @@
|
|||
/***************************************************************
|
||||
*
|
||||
* Calendar
|
||||
*
|
||||
* This classic desk accessory shows the calendar for the
|
||||
* current date. The arrow keys can be used to see calendars
|
||||
* for previous or future months.
|
||||
*
|
||||
* Commands (each is a single keystroke)
|
||||
*
|
||||
* up-arrow Look at the same month in the previous
|
||||
* year.
|
||||
* down-arrow Look at the same month in the next
|
||||
* year.
|
||||
* left-arrow Look at the previous month.
|
||||
* right-arrow Look at the next month.
|
||||
* ? or / Display help screen.
|
||||
* ESC Return to CDA main menu.
|
||||
*
|
||||
* Mike Westerfield
|
||||
*
|
||||
* Copyright 1987-1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
#pragma keep "Calendar"
|
||||
#pragma cda "Calendar" Start ShutDown
|
||||
#pragma lint -1
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <misctool.h>
|
||||
|
||||
#define LEFT_ARROW 0x08 /* key codes for legal commands */
|
||||
#define DOWN_ARROW 0x0A
|
||||
#define UP_ARROW 0x0B
|
||||
#define RIGHT_ARROW 0x15
|
||||
#define ESC 0x1B
|
||||
#define SLASH '/'
|
||||
#define QUESTION '?'
|
||||
|
||||
int ch; /* ord of last character read */
|
||||
int month, year; /* current month and year */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Factor: Computes the 'factor' for the first day of the
|
||||
* month. The factor is the number of days since
|
||||
* 31 Dec 0000.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
long Factor (long year, long month)
|
||||
|
||||
{
|
||||
if (month < 2)
|
||||
return 365 * year + 1 + 31 * month + (year - 1) / 4 -
|
||||
((year - 1) / 100 + 1) * 3 / 4;
|
||||
return 365 * year + 1 + 31 * month - ((month + 1) * 4 + 23) / 10 +
|
||||
year / 4 - (year / 100 + 1) * 3 / 4;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* GetKey: Returns the ordinal value of the next key typed
|
||||
* by the user.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
int GetKey (void)
|
||||
|
||||
{
|
||||
char ch, *cp;
|
||||
|
||||
cp = (char *) 0x00C000; /* wait for keypress */
|
||||
while ((*cp & 0x80) == 0) ;
|
||||
ch = *cp; /* save the key */
|
||||
cp = (char *) 0x00C010; /* clear the strobe */
|
||||
*cp = 0;
|
||||
return ch & 0x7F; /* return the key read */
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* GetThisMonth: Reads the clock to obtain today's month
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void GetThisMonth (void)
|
||||
|
||||
{
|
||||
time_t lt; /* encoded time */
|
||||
struct tm *ct; /* current time */
|
||||
|
||||
lt = time(NULL); /* get the coded time */
|
||||
ct = gmtime(<); /* convert to a decoded time */
|
||||
year = ct->tm_year + 1900; /* set the month/year */
|
||||
month = ct->tm_mon;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* GotoXY: Positions the cursor
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void GotoXY (int x, int y)
|
||||
|
||||
{
|
||||
putchar(0x1E);
|
||||
putchar(0x20 + x);
|
||||
putchar(0x20 + y);
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* PrintCalendar: Prints the calendar for the current
|
||||
* and year.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void PrintCalendar (void)
|
||||
|
||||
{
|
||||
#define TAB 26 /* disp of calendar from left edge */
|
||||
#define VTAB 5 /* disp of calendar from top */
|
||||
|
||||
int startDay, /* day of week for 1st day in month */
|
||||
numDays, /* # days in the month */
|
||||
nextMonth, nextYear, /* work variables */
|
||||
i, /* loop variable */
|
||||
vt, /* line # for next line of days */
|
||||
pos; /* day position for next date */
|
||||
|
||||
/* Compute day of week for 1st day in month */
|
||||
startDay = (int) ((Factor (year, month) - 1) % 7);
|
||||
nextMonth = month+1; /* compute # days in month */
|
||||
if (nextMonth == 12) {
|
||||
nextMonth = 0;
|
||||
nextYear = year+1;
|
||||
}
|
||||
else
|
||||
nextYear = year;
|
||||
numDays = (int) (Factor (nextYear, nextMonth) - Factor (year, month));
|
||||
|
||||
putchar(12); /* clear the screen */
|
||||
GotoXY(TAB+7, VTAB); /* position cursor */
|
||||
switch (month) { /* write the month */
|
||||
case 0: printf(" January "); break;
|
||||
case 1: printf("February "); break;
|
||||
case 2: printf(" March "); break;
|
||||
case 3: printf(" April "); break;
|
||||
case 4: printf(" May "); break;
|
||||
case 5: printf(" June "); break;
|
||||
case 6: printf(" July "); break;
|
||||
case 7: printf(" August "); break;
|
||||
case 8: printf("September "); break;
|
||||
case 9: printf(" October "); break;
|
||||
case 10: printf("November "); break;
|
||||
case 11: printf("December ");
|
||||
}
|
||||
printf("%d", year); /* write the year */
|
||||
GotoXY(TAB, VTAB+2); /* write the day header line */
|
||||
printf("Sun Mon Tue Wed Thu Fri Sat");
|
||||
vt = VTAB+4; /* set current date line */
|
||||
pos = 0; /* set day position */
|
||||
GotoXY(TAB-1, vt); /* position cursor for 1st line */
|
||||
for (i = 1; i <= startDay; i++) { /* skip over blank days */
|
||||
pos++;
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
/* Write the dates */
|
||||
for (i = 1; i <= numDays; i++) {
|
||||
printf("%4d", i);
|
||||
pos++;
|
||||
if (pos == 7) {
|
||||
pos = 0;
|
||||
vt += 2;
|
||||
GotoXY(TAB-1, vt);
|
||||
}
|
||||
}
|
||||
GotoXY(25, 23); /* write instructions */
|
||||
printf("Hit ? for help, or ESC to quit");
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* PrintHelp: Print the help screen.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void PrintHelp (void)
|
||||
|
||||
{
|
||||
int ch; /* dummy variable for reading keyboard */
|
||||
|
||||
putchar(0x0C); /* clear screen */
|
||||
printf( "This program recognizes the following single-keystroke commands:"
|
||||
"\n\n"
|
||||
" key action\n"
|
||||
" --- ------\n"
|
||||
" up-arrow Show the current month in the previous year.\n"
|
||||
" down-arrow Show the current month in the next year.\n"
|
||||
" left-arrow Show the previous month.\n"
|
||||
" right-arrow Show the next month.\n"
|
||||
" ESC exit the program.");
|
||||
|
||||
GotoXY(0, 23);
|
||||
printf("Hit any key to return to the program.");
|
||||
ch = GetKey();
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* Start: Body of calendar program
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
void Start(void)
|
||||
|
||||
{
|
||||
putchar('\006'); /* turn the cursor off */
|
||||
GetThisMonth(); /* find out what month it is */
|
||||
PrintCalendar(); /* print the calendar for this month */
|
||||
do {
|
||||
ch = GetKey(); /* get a command */
|
||||
switch (ch) {
|
||||
case LEFT_ARROW: {
|
||||
month--;
|
||||
if (month < 0) {
|
||||
month = 11;
|
||||
year--;
|
||||
}
|
||||
PrintCalendar();
|
||||
break;
|
||||
}
|
||||
|
||||
case RIGHT_ARROW: {
|
||||
month++;
|
||||
if (month > 11) {
|
||||
month = 0;
|
||||
year++;
|
||||
}
|
||||
PrintCalendar();
|
||||
break;
|
||||
}
|
||||
|
||||
case UP_ARROW: {
|
||||
year--;
|
||||
PrintCalendar();
|
||||
break;
|
||||
}
|
||||
|
||||
case DOWN_ARROW: {
|
||||
year++;
|
||||
PrintCalendar();
|
||||
break;
|
||||
}
|
||||
|
||||
case QUESTION:
|
||||
case SLASH: {
|
||||
PrintHelp();
|
||||
PrintCalendar();
|
||||
break;
|
||||
}
|
||||
|
||||
case ESC: return;
|
||||
|
||||
default:
|
||||
SysBeep();
|
||||
}
|
||||
}
|
||||
while (1);
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* ShutDown: Does nothing
|
||||
*
|
||||
*************************************************************/
|
||||
|
||||
void ShutDown(void)
|
||||
|
||||
{
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/****************************************************************
|
||||
*
|
||||
* Echo
|
||||
*
|
||||
* This is about the simplest a classic desk accessory can be,
|
||||
* providing a quick framework for developing your own. It
|
||||
* simply reads strings typed from the keyboard and echos
|
||||
* them back to the screen.
|
||||
*
|
||||
* Mike Westerfield
|
||||
*
|
||||
* Copyright 1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
#pragma keep "Echo"
|
||||
#pragma cda "Echo from C" Start ShutDown
|
||||
#pragma lint -1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
char str[256];
|
||||
|
||||
|
||||
void Start(void)
|
||||
|
||||
{
|
||||
printf("This program echoes the strings you type from the keyboard. To\n");
|
||||
printf("quit, hit the RETURN key at the beginning of a line.\n\n");
|
||||
|
||||
do {
|
||||
fgets(str, 256, stdin); /* read a string */
|
||||
printf("%s\n", str); /* write the same string */
|
||||
}
|
||||
while (strlen(str) > 1); /* quit if the string is empty */
|
||||
}
|
||||
|
||||
|
||||
void ShutDown(void)
|
||||
|
||||
{
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/****************************************************************/
|
||||
/* */
|
||||
/* Hello World CDev */
|
||||
/* */
|
||||
/* Mike Westerfield */
|
||||
/* October 1991 */
|
||||
/* */
|
||||
/* Copyright 1991 */
|
||||
/* Byte Works, Inc. */
|
||||
/* All Rights Reserved. */
|
||||
/* */
|
||||
/****************************************************************/
|
||||
/* */
|
||||
/* This CDev displays a text message. It can be used as a */
|
||||
/* framework for developing your own CDevs. */
|
||||
/* */
|
||||
/* For detailed information about CDevs, see Apple II File */
|
||||
/* Type Notes for file type $D8. Apple II File Type Notes */
|
||||
/* are available from major online services, large users */
|
||||
/* groups, or from APDA. */
|
||||
/* */
|
||||
/****************************************************************/
|
||||
|
||||
#pragma keep "worldobj"
|
||||
#pragma cdev Driver
|
||||
#pragma lint -1
|
||||
|
||||
#include <types.h>
|
||||
#include <control.h>
|
||||
#include <quickdraw.h>
|
||||
|
||||
|
||||
GrafPortPtr wPtr; /* our window pointer */
|
||||
|
||||
|
||||
/* DoAbout - Show the help info */
|
||||
|
||||
void DoAbout (void)
|
||||
|
||||
{
|
||||
NewControl2(wPtr, 0x0009, 257L); /* draw the text (it's a stattext control) */
|
||||
}
|
||||
|
||||
|
||||
/* DoCreate - Create the controls */
|
||||
|
||||
void DoCreate (void)
|
||||
|
||||
{
|
||||
NewControl2(wPtr, 0x0009, 256L); /* create the controls */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Driver - main entry point */
|
||||
|
||||
long Driver (long data2, long data1, int message)
|
||||
|
||||
#define createCDev 7 /* message numbers */
|
||||
#define aboutCDev 8
|
||||
|
||||
{
|
||||
wPtr = (void *) data1; /* get our window pointer (most calls) */
|
||||
switch (message) {
|
||||
case createCDev: DoCreate();
|
||||
break;
|
||||
case aboutCDev: DoAbout();
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
cmpl +t +e -x worldcdev.cc
|
||||
compile +t +e worldcdev.rez keep=WorldCDev
|
||||
filetype WorldCDev $C7
|
|
@ -0,0 +1,110 @@
|
|||
#include "types.rez"
|
||||
|
||||
/* This is the required resource to tell the control panel about the CDev */
|
||||
resource rCDEVFlags (0x1) {
|
||||
0x00C0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
{0, 0, 110, 200},
|
||||
"Hello World",
|
||||
"Mike Westerfield",
|
||||
"1.0"
|
||||
};
|
||||
|
||||
/* Code resource; the executable part of the CDev */
|
||||
read rCDevCode (0x1,convert) "worldobj";
|
||||
|
||||
/* This is the icon displayed by the control panel */
|
||||
resource rIcon (0x1) {
|
||||
0x8000, /* color icon */
|
||||
20, /* height in pixels */
|
||||
28, /* width in pixels */
|
||||
$"FFFFFFFFFFF1111111FFFFFFFFFF"
|
||||
$"FFFFFFFF111111111111FFFFFFFF"
|
||||
$"FFFFFF1111118881111881FFFFFF"
|
||||
$"FFFFF111888888888818811FFFFF"
|
||||
$"FFFF11118888888888118111FFFF"
|
||||
$"FFF1111111888888811111111FFF"
|
||||
$"FFF1111111888888111111111FFF"
|
||||
$"FF111111111881181111111111FF"
|
||||
$"FF111111111181111111111111FF"
|
||||
$"FF111111111181111111111111FF"
|
||||
$"FF111111118888881111111111FF"
|
||||
$"FF111111118888888111111111FF"
|
||||
$"FFF1111111888888811111111FFF"
|
||||
$"FFF1111111188888111111111FFF"
|
||||
$"FFFF11111111888811111111FFFF"
|
||||
$"FFFFF111111118811111111FFFFF"
|
||||
$"FFFFFF1111111181111111FFFFFF"
|
||||
$"FFFFFFFF111111111111FFFFFFFF"
|
||||
$"FFFFFFFFFF11111111FFFFFFFFFF"
|
||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
||||
|
||||
$"00000000000FFFFFFF0000000000"
|
||||
$"00000000FFFFFFFFFFFF00000000"
|
||||
$"000000FFFFFFFFFFFFFFFF000000"
|
||||
$"00000FFFFFFFFFFFFFFFFFF00000"
|
||||
$"0000FFFFFFFFFFFFFFFFFFFF0000"
|
||||
$"000FFFFFFFFFFFFFFFFFFFFFF000"
|
||||
$"000FFFFFFFFFFFFFFFFFFFFFF000"
|
||||
$"00FFFFFFFFFFFFFFFFFFFFFFFF00"
|
||||
$"00FFFFFFFFFFFFFFFFFFFFFFFF00"
|
||||
$"00FFFFFFFFFFFFFFFFFFFFFFFF00"
|
||||
$"00FFFFFFFFFFFFFFFFFFFFFFFF00"
|
||||
$"00FFFFFFFFFFFFFFFFFFFFFFFF00"
|
||||
$"000FFFFFFFFFFFFFFFFFFFFFF000"
|
||||
$"000FFFFFFFFFFFFFFFFFFFFFF000"
|
||||
$"0000FFFFFFFFFFFFFFFFFFFF0000"
|
||||
$"00000FFFFFFFFFFFFFFFFFF00000"
|
||||
$"000000FFFFFFFFFFFFFFFF000000"
|
||||
$"00000000FFFFFFFFFFFF00000000"
|
||||
$"0000000000FFFFFFFF0000000000"
|
||||
$"0000000000000000000000000000"
|
||||
};
|
||||
|
||||
/* The following resources define the various controls in the main display */
|
||||
resource rControlList (256) {
|
||||
{
|
||||
256,
|
||||
};
|
||||
};
|
||||
|
||||
resource rControlTemplate (256) {
|
||||
0x00000001, /* control id */
|
||||
{38,5,49,205}, /* control rectangle */
|
||||
statTextControl {{ /* control type */
|
||||
0x0000, /* flags */
|
||||
0x1002, /* more flags */
|
||||
0, /* ref con */
|
||||
256, /* text reference */
|
||||
13 /* text length */
|
||||
}};
|
||||
};
|
||||
resource rTextForLETextBox2 (256) {
|
||||
"Hello, world."
|
||||
};
|
||||
|
||||
/* The following resources define the controls for the help screen */
|
||||
resource rControlList (257) {
|
||||
{
|
||||
257,
|
||||
};
|
||||
};
|
||||
|
||||
resource rControlTemplate (257) {
|
||||
0x00000002, /* control id */
|
||||
{38,5,49,205}, /* control rectangle */
|
||||
statTextControl {{ /* control type */
|
||||
0x0000, /* flags */
|
||||
0x1002, /* more flags */
|
||||
0, /* ref con */
|
||||
257, /* text reference */
|
||||
19 /* text length */
|
||||
}};
|
||||
};
|
||||
resource rTextForLETextBox2 (257) {
|
||||
"Put help info here."
|
||||
};
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
/**************************************************************
|
||||
*
|
||||
* This desk accessory brings up a simple clock. It can be
|
||||
* used as an outline when creating more complex desk accessories.
|
||||
*
|
||||
* Original Pascal version by Phil Montoya
|
||||
* C Translation by Mike Westerfield
|
||||
*
|
||||
* Copyright 1987,1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
#pragma keep "Clock"
|
||||
#pragma nda Open Close Action Init 60 0xFFFF "--Clock\\H**"
|
||||
#pragma lint -1
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <quickdraw.h>
|
||||
#include <misctool.h>
|
||||
#include <event.h>
|
||||
#include <desk.h>
|
||||
#include <window.h>
|
||||
|
||||
#define TRUE 1 /* boolean constants */
|
||||
#define FALSE 0
|
||||
|
||||
int clockActive = 0; /* are we already active flag */
|
||||
GrafPortPtr clockWinPtr; /* window pointer */
|
||||
|
||||
char title[] = "\pClock"; /* window title */
|
||||
ParamList clockWin = { /* new window record */
|
||||
78, /* paramLength */
|
||||
0xC0A0, /* wFrameBits */
|
||||
title, /* wTitle */
|
||||
0L, /* wRefCon */
|
||||
{0,0,0,0}, /* wZoom */
|
||||
NULL, /* wColor */
|
||||
0,0, /* wYOrigin,wXOrigin */
|
||||
0,0, /* wDataH,wDataW */
|
||||
0,0, /* wMaxH,wMaxW */
|
||||
0,0, /* wScrollVer,wScrollHor */
|
||||
0,0, /* wPageVer,wPageHor */
|
||||
0, /* wInfoRefCon */
|
||||
0, /* wInfoHeight */
|
||||
NULL, /* wFrameDefProc */
|
||||
NULL, /* wInfoDefProc */
|
||||
NULL, /* wContDefProc */
|
||||
{50,50,62,200}, /* wPosition */
|
||||
(void *) -1L, /* wPlane */
|
||||
NULL /* wStorage */
|
||||
};
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* DrawTime - Reads the time and draws it in the window
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
void DrawTime (void)
|
||||
|
||||
{
|
||||
int i; /* index variable */
|
||||
char timeString[21]; /* string to hold time */
|
||||
|
||||
ReadAsciiTime(timeString);
|
||||
timeString[20] = 0;
|
||||
for (i = 0; i < 20; i++)
|
||||
timeString[i] &= 0x7F;
|
||||
MoveTo(7, 10);
|
||||
DrawCString(timeString);
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* Open - opens the desk accessory if it is not already active
|
||||
*
|
||||
* Outputs:
|
||||
* GrafPortPtr - pointer to desk accessory window
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
GrafPortPtr Open (void)
|
||||
|
||||
{
|
||||
if (!clockActive) {
|
||||
clockWinPtr = NewWindow(&clockWin); /* open a window */
|
||||
SetSysWindow(clockWinPtr); /* set it to the system window */
|
||||
clockActive = TRUE; /* we are now active */
|
||||
return clockWinPtr; /* return our window pointer */
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* Close - closes the desk accessory if it is active
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
void Close(void)
|
||||
|
||||
{
|
||||
if (clockActive) {
|
||||
CloseWindow(clockWinPtr);
|
||||
clockActive = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* Action - Handle an action call
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
void Action (long param, int code)
|
||||
|
||||
{
|
||||
EventRecordPtr evPtr;
|
||||
GrafPortPtr currPort;
|
||||
|
||||
switch (code) {
|
||||
|
||||
case eventAction: {
|
||||
evPtr = (EventRecordPtr) param;
|
||||
if (evPtr->what == updateEvt) {
|
||||
BeginUpdate(clockWinPtr);
|
||||
DrawTime();
|
||||
EndUpdate(clockWinPtr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
case runAction: {
|
||||
currPort = GetPort();
|
||||
SetPort(clockWinPtr);
|
||||
DrawTime();
|
||||
SetPort(currPort);
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
*
|
||||
* Initialization
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
void Init(int code)
|
||||
|
||||
{
|
||||
if (code == 0) {
|
||||
if (clockActive)
|
||||
Close();
|
||||
}
|
||||
else
|
||||
clockActive = FALSE;
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
/****************************************************************
|
||||
*
|
||||
* Frame
|
||||
*
|
||||
* This desktop program is about as simple as they get. It
|
||||
* brings up the Apple menu, a file menu with Quit and Close,
|
||||
* and an edit menu with Undo, Cut, Copy, Paste and Clear.
|
||||
* This is the minimum configuration for supporting desk
|
||||
* accessories. (All of these menus have pre-assigned numbers,
|
||||
* assigned by Apple.)
|
||||
*
|
||||
* The purpose of this rather simple program is to show how
|
||||
* easy a desktop program can be to write, and to give you a
|
||||
* framework to use in developing your own programs.
|
||||
*
|
||||
* Mike Westerfield
|
||||
*
|
||||
* Copyright 1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
#pragma keep "Frame"
|
||||
#pragma lint -1
|
||||
|
||||
#include <orca.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <types.h>
|
||||
#include <quickdraw.h>
|
||||
#include <misctool.h>
|
||||
#include <event.h>
|
||||
#include <control.h>
|
||||
#include <window.h>
|
||||
#include <menu.h>
|
||||
#include <desk.h>
|
||||
#include <lineedit.h>
|
||||
#include <dialog.h>
|
||||
|
||||
#define apple_About 257 /* Menu ID numbers */
|
||||
#define file_Quit 256
|
||||
|
||||
enum alertKind {norml, stop, note, caution}; /* kinds of alerts */
|
||||
|
||||
typedef int BOOL; /* simulate boolean types */
|
||||
BOOL done; /* tells if the program should stop */
|
||||
WmTaskRec lastEvent; /* last event returned in event loop */
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* DoAlert - Create an alert box
|
||||
*
|
||||
* Input:
|
||||
* kind - kind of alert
|
||||
* msg - alert message
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void DoAlert (enum alertKind kind, char *msg)
|
||||
|
||||
{
|
||||
static ItemTemplate button = /* button item */
|
||||
{ 1, 36, 15, 0, 0, buttonItem, "\pOK", 0, 0, NULL };
|
||||
|
||||
static ItemTemplate message = /* message item */
|
||||
{ 100, 5, 100, 90, 280, itemDisable+statText, NULL, 0, 0, NULL };
|
||||
|
||||
static AlertTemplate alertRec = /* alert box */
|
||||
{ 50, 180, 107, 460, 2, 0x80, 0x80, 0x80, 0x80, NULL, NULL, NULL };
|
||||
|
||||
|
||||
SetForeColor (0); /* set text colors */
|
||||
SetBackColor (15);
|
||||
|
||||
message.itemDescr = msg; /* init. non-constant */
|
||||
alertRec.atItemList [0] = (ItemTempPtr) &button; /* template fields */
|
||||
alertRec.atItemList [1] = (ItemTempPtr) &message;
|
||||
|
||||
switch (kind) {
|
||||
case norml: Alert (&alertRec, NULL);
|
||||
break;
|
||||
|
||||
case stop: StopAlert (&alertRec, NULL);
|
||||
break;
|
||||
|
||||
case note: NoteAlert (&alertRec, NULL);
|
||||
break;
|
||||
|
||||
case caution: CautionAlert (&alertRec, NULL);
|
||||
break;
|
||||
|
||||
default: printf ("Error in DoAlert\n");
|
||||
exit (-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* MenuAbout - Create the About menu
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void MenuAbout (void)
|
||||
|
||||
{
|
||||
DoAlert (note, "\pFrame 1.0\r"
|
||||
"Copyright 1989\r"
|
||||
"Byte Works, Inc.\r\r"
|
||||
"By Mike Westerfield");
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* HandleMenu - Handle a menu selection
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void HandleMenu (int menuNum)
|
||||
|
||||
{
|
||||
switch (menuNum) {
|
||||
case apple_About: MenuAbout ();
|
||||
break;
|
||||
|
||||
case file_Quit: done = TRUE;
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
HiliteMenu (FALSE, (int) (lastEvent.wmTaskData >> 16));
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* InitMenus - Initialize the menu bar
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void InitMenus (void)
|
||||
|
||||
{
|
||||
InsertMenu (NewMenu (">> Edit \\N3\r" /* create the edit menu */
|
||||
"--Undo\\N250V*Zz\r"
|
||||
"--Cut\\N251*Xx\r"
|
||||
"--Copy\\N252*Cc\r"
|
||||
"--Paste\\N253*Vv\r"
|
||||
"--Clear\\N254\r"
|
||||
".\r"), 0);
|
||||
|
||||
InsertMenu (NewMenu (">> File \\N2\r" /* create the file menu */
|
||||
"--Close\\N255V\r"
|
||||
"--Quit\\N256*Qq\r"
|
||||
".\r"), 0);
|
||||
|
||||
InsertMenu (NewMenu (">>@\\XN1\r" /* create the Apple menu */
|
||||
"--About Frame\\N257V\r"
|
||||
".\r"), 0);
|
||||
|
||||
FixAppleMenu (1); /* add desk accessories */
|
||||
FixMenuBar (); /* draw the completed menu bar */
|
||||
DrawMenuBar ();
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Main Program
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
int main (void)
|
||||
|
||||
{
|
||||
int event; /* event # returned by TaskMaster */
|
||||
|
||||
startdesk (640);
|
||||
InitMenus (); /* set up the menu bar */
|
||||
lastEvent.wmTaskMask = 0x1FFFL; /* let Task Master do most stuff */
|
||||
ShowCursor (); /* show the cursor */
|
||||
|
||||
done = FALSE; /* main event loop */
|
||||
do {
|
||||
event = TaskMaster (0x076E, &lastEvent);
|
||||
switch (event) { /* handle the events we need to */
|
||||
case wInSpecial:
|
||||
case wInMenuBar: HandleMenu ((int) lastEvent.wmTaskData);
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
while (!done);
|
||||
enddesk ();
|
||||
}
|
|
@ -0,0 +1,374 @@
|
|||
/****************************************************************
|
||||
*
|
||||
* MiniCAD
|
||||
*
|
||||
* MiniCAD is a (very) simple CAD program based on the Frame
|
||||
* program. With MiniCAD, you can open new windows, close
|
||||
* windows that are on the desktop, and draw lines using the
|
||||
* mouse. Multiple windows are supported.
|
||||
*
|
||||
* Mike Westerfield
|
||||
*
|
||||
* Copyright 1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
#pragma keep "MiniCAD"
|
||||
#pragma lint -1
|
||||
|
||||
#include <orca.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <types.h>
|
||||
#include <quickdraw.h>
|
||||
#include <misctool.h>
|
||||
#include <event.h>
|
||||
#include <control.h>
|
||||
#include <window.h>
|
||||
#include <menu.h>
|
||||
#include <desk.h>
|
||||
#include <lineedit.h>
|
||||
#include <dialog.h>
|
||||
|
||||
#define apple_About 257 /* Menu ID #s */
|
||||
#define file_Quit 256
|
||||
#define file_New 258
|
||||
#define file_Close 255
|
||||
|
||||
#define maxWindows 4 /* max # of drawing windows */
|
||||
#define maxLines 50 /* max # of lines in a window */
|
||||
|
||||
typedef int BOOL; /* simulate boolean types */
|
||||
typedef struct { Point p1, p2; } lineRecord; /* line defined by its endpts */
|
||||
|
||||
/* holds info about 1 window */
|
||||
struct windowRecord { GrafPortPtr wPtr; /* ptr to the window's port */
|
||||
char *name; /* name of the window */
|
||||
int numLines; /* # lines in this window */
|
||||
lineRecord lines [maxLines]; /* lines in drawing */
|
||||
};
|
||||
|
||||
enum alertKind {norml, stop, note, caution}; /* kinds of alerts */
|
||||
|
||||
BOOL done; /* tells if the program should stop */
|
||||
WmTaskRec lastEvent; /* last event returned in event loop */
|
||||
|
||||
static struct windowRecord windows [maxWindows] = /* drawing windows */
|
||||
{ { NULL, "\pPaint 1" }, { NULL, "\pPaint 2" },
|
||||
{ NULL, "\pPaint 3" }, { NULL, "\pPaint 4" } };
|
||||
|
||||
static ParamList wParms = /* parameters for NewWindow */
|
||||
{ 78, 0xDDA7, NULL, 0, 0, 615, 25, 188, NULL, 0, 0, 0, 0, 0, 0, 10, 10,
|
||||
0, 0, 0, 0, NULL, NULL, NULL, 25, 0, 188, 615, NULL, NULL };
|
||||
|
||||
static ItemTemplate button = /* button item */
|
||||
{ 1, 36, 15, 0, 0, buttonItem, "\pOK", 0, 0, NULL };
|
||||
|
||||
static ItemTemplate message = /* message item */
|
||||
{ 100, 5, 100, 90, 280, itemDisable+statText, NULL, 0, 0, NULL };
|
||||
|
||||
static AlertTemplate alertRec = /* alert box */
|
||||
{ 50, 180, 107, 460, 2, 0x80, 0x80, 0x80, 0x80, NULL, NULL, NULL };
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* DoAlert - Create an alert box
|
||||
*
|
||||
* Input:
|
||||
* kind - kind of alert
|
||||
* msg - alert message
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void DoAlert (enum alertKind kind, char *msg)
|
||||
|
||||
{
|
||||
SetForeColor (0); /* set text colors */
|
||||
SetBackColor (15);
|
||||
|
||||
message.itemDescr = msg; /* init. non-constant */
|
||||
alertRec.atItemList [0] = (ItemTempPtr) &button; /* template fields */
|
||||
alertRec.atItemList [1] = (ItemTempPtr) &message;
|
||||
|
||||
switch (kind) {
|
||||
case norml: Alert (&alertRec, NULL);
|
||||
break;
|
||||
|
||||
case stop: StopAlert (&alertRec, NULL);
|
||||
break;
|
||||
|
||||
case note: NoteAlert (&alertRec, NULL);
|
||||
break;
|
||||
|
||||
case caution: CautionAlert (&alertRec, NULL);
|
||||
break;
|
||||
|
||||
default: printf ("Error in DoAlert\n");
|
||||
exit (-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma databank 1
|
||||
/****************************************************************
|
||||
*
|
||||
* DrawWindow - Draw the contents of the current window
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void DrawWindow (void)
|
||||
|
||||
{
|
||||
int i; /* window's index */
|
||||
int j; /* loop variable */
|
||||
|
||||
struct windowRecord *wp; /* work pointers */
|
||||
lineRecord *lp;
|
||||
|
||||
i = GetWRefCon (GetPort());
|
||||
if (windows [i].numLines) { /* skip the work if there */
|
||||
/* aren't any lines */
|
||||
SetPenMode (modeCopy); /* set up to draw */
|
||||
SetSolidPenPat (0);
|
||||
SetPenSize (2, 1);
|
||||
wp = &windows [i]; /* draw each of the lines */
|
||||
for (j = 0; j < wp->numLines; ++j) {
|
||||
lp = &(wp->lines [j]);
|
||||
MoveTo (lp->p1.h, lp->p1.v);
|
||||
LineTo (lp->p2.h, lp->p2.v);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma databank 0
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* DoClose - Close the front drawing window, if there is one
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void DoClose (void)
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
if (FrontWindow () != NULL) {
|
||||
i = GetWRefCon (FrontWindow ());
|
||||
CloseWindow (windows [i].wPtr);
|
||||
windows [i].wPtr = NULL;
|
||||
EnableMItem (file_New);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* MenuAbout - Create the About alert box
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void MenuAbout (void)
|
||||
|
||||
{
|
||||
DoAlert (note, "\pMini-CAD 1.0\r"
|
||||
"Copyright 1989\r"
|
||||
"Byte Works, Inc.\r\r"
|
||||
"By Mike Westerfield");
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* DoNew - Open a new drawing window
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void DoNew (void)
|
||||
|
||||
{
|
||||
int i; /* index variable */
|
||||
|
||||
i = 0; /* find an empty record */
|
||||
while (windows[i].wPtr != NULL)
|
||||
++i;
|
||||
windows[i].numLines = 0; /* no lines drawn yet */
|
||||
|
||||
wParms.wTitle = (Pointer) windows[i].name; /* init. non-constant */
|
||||
wParms.wRefCon = i; /* wParms fields */
|
||||
wParms.wContDefProc = (VoidProcPtr) DrawWindow;
|
||||
wParms.wPlane = (GrafPortPtr) topMost;
|
||||
|
||||
windows[i].wPtr = NewWindow (&wParms); /* open the window */
|
||||
if (toolerror()) {
|
||||
DoAlert (stop, "\pError opening the window.");
|
||||
windows [i].wPtr = NULL;
|
||||
}
|
||||
else if (i == 3) /* don't allow more than 4 open windows */
|
||||
DisableMItem (file_New);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* HandleMenu - Handle a menu selection
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void HandleMenu (int menuNum)
|
||||
|
||||
{
|
||||
switch (menuNum) {
|
||||
case apple_About: MenuAbout();
|
||||
break;
|
||||
|
||||
case file_Quit: done = TRUE;
|
||||
break;
|
||||
|
||||
case file_New: DoNew ();
|
||||
break;
|
||||
|
||||
case file_Close: DoClose ();
|
||||
}
|
||||
HiliteMenu (FALSE, (int) (lastEvent.wmTaskData >> 16));
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* InitMenus - Initialize the menu bar
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void InitMenus (void)
|
||||
|
||||
{
|
||||
InsertMenu (NewMenu (">> Edit \\N3\r" /* create the edit menu */
|
||||
"--Undo\\N250V*Zz\r"
|
||||
"--Cut\\N251*Xx\r"
|
||||
"--Copy\\N252*Cc\r"
|
||||
"--Paste\\N253*Vv\r"
|
||||
"--Clear\\N254\r"
|
||||
".\r"), 0);
|
||||
|
||||
InsertMenu (NewMenu (">> File \\N2\r" /* create the file menu */
|
||||
"--New\\N258*Nn\r"
|
||||
"--Close\\N255V\r"
|
||||
"--Quit\\N256*Qq\r"
|
||||
".\r"), 0);
|
||||
|
||||
InsertMenu (NewMenu (">>@\\XN1\r" /* create the Apple menu */
|
||||
"--About...\\N257V\r"
|
||||
".\r"), 0);
|
||||
|
||||
FixAppleMenu (1); /* add desk accessories */
|
||||
FixMenuBar (); /* draw the completed menu bar */
|
||||
DrawMenuBar ();
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Sketch - Track the mouse, drawing lines to connect the points
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void Sketch (void)
|
||||
|
||||
{
|
||||
Point endPoint; /* the end point of the line */
|
||||
Point firstPoint; /* the initial point */
|
||||
int i; /* window index */
|
||||
int numLines; /* copy of windows [i].numLines */
|
||||
EventRecord sEvent; /* last event returned in event loop */
|
||||
|
||||
/* get the window's index */
|
||||
i = GetWRefCon (FrontWindow());
|
||||
|
||||
/* check for too many lines */
|
||||
if (windows [i].numLines == maxLines)
|
||||
DoAlert (stop, "\pThe window is full -\rmore lines cannot be\radded.");
|
||||
else {
|
||||
/* initialize the pen */
|
||||
StartDrawing (FrontWindow());
|
||||
SetSolidPenPat (15);
|
||||
SetPenSize (2, 1);
|
||||
SetPenMode (modeXOR);
|
||||
|
||||
/* record the initial pen location */
|
||||
firstPoint = lastEvent.where;
|
||||
GlobalToLocal (&firstPoint);
|
||||
MoveTo (firstPoint.h, firstPoint.v);
|
||||
LineTo (firstPoint.h, firstPoint.v);
|
||||
endPoint = firstPoint;
|
||||
|
||||
/* follow the pen, rubber-banding the line */
|
||||
while (!GetNextEvent (mUpMask, &sEvent)) {
|
||||
GlobalToLocal (&sEvent.where);
|
||||
if ((endPoint.h != sEvent.where.h) || (endPoint.v != sEvent.where.v)) {
|
||||
MoveTo (firstPoint.h, firstPoint.v);
|
||||
LineTo (endPoint.h, endPoint.v);
|
||||
MoveTo (firstPoint.h, firstPoint.v);
|
||||
LineTo (sEvent.where.h, sEvent.where.v);
|
||||
endPoint.h = sEvent.where.h;
|
||||
endPoint.v = sEvent.where.v;
|
||||
}
|
||||
}
|
||||
|
||||
/* erase the last XORed line */
|
||||
MoveTo (firstPoint.h, firstPoint.v);
|
||||
LineTo (endPoint.h, endPoint.v);
|
||||
|
||||
/* if we have a line (not a point), record it in window's line list */
|
||||
if ((firstPoint.h != endPoint.h) || (firstPoint.v != endPoint.v)) {
|
||||
numLines = windows[i].numLines++;
|
||||
windows [i].lines [numLines].p1 = firstPoint;
|
||||
windows [i].lines [numLines].p2 = endPoint;
|
||||
SetPenMode (modeCopy);
|
||||
SetSolidPenPat (0);
|
||||
MoveTo (firstPoint.h, firstPoint.v);
|
||||
LineTo (endPoint.h, endPoint.v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Program begins here
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
int main (void)
|
||||
|
||||
{
|
||||
int event; /* event #; returned by TaskMaster */
|
||||
|
||||
startdesk (640);
|
||||
InitMenus (); /* set up the menu bar */
|
||||
lastEvent.wmTaskMask = 0x1FFFL; /* let task master do most stuff */
|
||||
ShowCursor (); /* show the cursor */
|
||||
|
||||
done = FALSE; /* main event loop */
|
||||
do {
|
||||
event = TaskMaster (0x076E, &lastEvent);
|
||||
switch (event) { /* handle the events we need to */
|
||||
case wInSpecial:
|
||||
case wInMenuBar: HandleMenu ((int) lastEvent.wmTaskData);
|
||||
break;
|
||||
|
||||
case wInGoAway : DoClose ();
|
||||
break;
|
||||
|
||||
case wInContent: Sketch ();
|
||||
}
|
||||
}
|
||||
while (!done);
|
||||
enddesk ();
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,167 @@
|
|||
/****************************************************************
|
||||
*
|
||||
* A simple graphics demo.
|
||||
*
|
||||
* By Phil Montoya and Barbara Allred
|
||||
*
|
||||
* Copyright 1987-1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
#pragma keep "Bounce"
|
||||
#pragma lint -1
|
||||
|
||||
#include <quickdraw.h>
|
||||
#include <orca.h>
|
||||
|
||||
#define screenMode 640 /* 640x200 graphics Super HiRes display mode */
|
||||
#define copyMode 0 /* pen copy mode */
|
||||
#define size 6 /* number of points */
|
||||
|
||||
/* Global variables */
|
||||
|
||||
static int curColor = white; /* pen color */
|
||||
static int curSize = 1; /* no. points-1 */
|
||||
static int x[size]; /* initial points */
|
||||
static int y[size];
|
||||
static int xv[size], yv[size]; /* move and velocity arrays */
|
||||
static int maxX, maxY; /* max X, Y coordinates */
|
||||
static int minX, minY; /* min X, Y coordinates */
|
||||
static Rect r; /* drawing rectangle */
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* UpDate - Updates x and y by velocity factors and changes
|
||||
* direction if necessary
|
||||
*
|
||||
* Inputs:
|
||||
* px - X location
|
||||
* pxv - X velocity
|
||||
* py - Y location
|
||||
* pyv - Y velocity
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void UpDate (int *px, int *pxv, int *py, int *pyv)
|
||||
|
||||
{
|
||||
*px += *pxv; /* move x by velocity factor */
|
||||
if ((*px < minX) || (*px > maxX)) { /* if x is beyond border... */
|
||||
*px -= *pxv; /* ...move back */
|
||||
*pxv = -(*pxv); /* ...change directions */
|
||||
}
|
||||
*py += *pyv; /* move y by velocity factor */
|
||||
if ((*py < minY) || (*py > maxY)) { /* if y is beyond border... */
|
||||
*py -= *pyv; /* ...move back */
|
||||
*pyv = -(*pyv); /* ...change directions */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* NextPenColor - Changes the pen color
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void NextPenColor (void)
|
||||
|
||||
{
|
||||
curColor++; /* get next color */
|
||||
if (curColor > white) /* if out of colors then start over */
|
||||
curColor = black;
|
||||
SetSolidPenPat(curColor); /* set the pen to this color */
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Initialize - initialization for program
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void Initialize (void)
|
||||
|
||||
{
|
||||
int i, j;
|
||||
|
||||
SetPenSize(4, 2); /* use a fatter pen */
|
||||
SetPenMode(copyMode); /* use the copy pen mode */
|
||||
GetPortRect(&r);
|
||||
maxX = r.h2; maxY = r.v2; /* don't go beyond screen edges */
|
||||
minX = r.h1; minY = r.v1;
|
||||
|
||||
i = maxX - minX; /* set initial points */
|
||||
j = maxX >> 1;
|
||||
x[0] = minX + j + 20; x[1] = minX + j - 20;
|
||||
x[2] = x[3] = x[4] = x[5] = minX + j;
|
||||
|
||||
i = maxY - minY;
|
||||
j = maxY >> 1;
|
||||
y[3] = minY + j + 10; y[4] = minY + j - 10;
|
||||
y[0] = y[1] = y[2] = y[5] = minY + j;
|
||||
|
||||
for (i = 0, j = 6; i < size; i++) { /* set velocity factors */
|
||||
if (i & 0x0001) /* if i is odd... */
|
||||
j = -j;
|
||||
yv [i] = j;
|
||||
xv [i] = -j;
|
||||
j -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* DrawShapes - This is the engine of the demo.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
void DrawShapes (void)
|
||||
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
for (k = white; k >= black; k--) { /* cycle thru 16 screens */
|
||||
SetSolidPenPat(k); /* set the background color */
|
||||
PaintRect(&r);
|
||||
|
||||
/* The number of shapes per screen depends on the size of the shape. */
|
||||
/* The more points a shape has the less times it will be drawn and */
|
||||
/* vice-versa. This keeps the time and density per screen approximately */
|
||||
/* the same. */
|
||||
|
||||
for (i = 0; i < (((size-curSize) * 38) + 75); i++) {
|
||||
/* draw this series of shapes */
|
||||
NextPenColor (); /* change pen colors */
|
||||
MoveTo (x[curSize], y[curSize]); /* initial from position */
|
||||
UpDate (x+curSize, xv+curSize, y+curSize, yv+curSize);
|
||||
for (j = 0; j < curSize; j++) { /* draw this shape */
|
||||
LineTo (x[j], y[j]);
|
||||
UpDate (x+j, xv+j, y+j, yv+j);
|
||||
}
|
||||
}
|
||||
curSize++; /* next shape size */
|
||||
if (curSize == size)
|
||||
curSize = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Program Begins Here
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
int main (void)
|
||||
|
||||
{
|
||||
startgraph(screenMode); /* set up graphics screen */
|
||||
Initialize(); /* initialize global data */
|
||||
DrawShapes(); /* draw the shapes */
|
||||
endgraph(); /* shut down the graphics screen */
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*****************************************************************
|
||||
*
|
||||
* Call GS/OS
|
||||
*
|
||||
* This program shows how to call GS/OS directly. You should
|
||||
* compare it with callp16.cc, which shows how to call ProDOS 16
|
||||
* (an older operating system that is now a subset of GS/OS).
|
||||
*
|
||||
* This program dumps the contents of a screen image file to the
|
||||
* graphics screen. It is assumed that the program callp16 was
|
||||
* executed prior to running this program, and that you have
|
||||
* made a note of the filename containing the screen dump that
|
||||
* was created by callp16.
|
||||
*
|
||||
* DO NOT EXECUTE THIS PROGRAM FROM THE DESKTOP. It uses non-
|
||||
* standard mechanisms for accessing the graphics screen.
|
||||
*
|
||||
* By Barbara Allred and Mike Westerfield
|
||||
*
|
||||
* Copyright 1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
#pragma keep "CallGSOS"
|
||||
#pragma debug 1 /* check stack overflows */
|
||||
#pragma lint -1
|
||||
|
||||
#include <types.h>
|
||||
#include <stdlib.h>
|
||||
#include <orca.h>
|
||||
#include <quickdraw.h>
|
||||
#include <gsos.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SCREENWIDTH 320 /* screen width in pixels */
|
||||
|
||||
static GSString255 filename; /* name of file having screen contents */
|
||||
|
||||
/* Data Control Blocks for GS/OS calls */
|
||||
OpenRecGS openDCB = { 15, 0, NULL, 1, 0};
|
||||
IORecGS readDCB = { 5, 0, (void *) 0x00E12000, 32768L, 0L, 0 };
|
||||
RefNumRecGS closeDCB = { 1, 0 };
|
||||
|
||||
int main (void)
|
||||
|
||||
{
|
||||
char *str;
|
||||
int i;
|
||||
|
||||
/* Prompt user for the name of the file to load. */
|
||||
printf ("Please enter the name of the file containing the screen image:\n");
|
||||
scanf ("%s", filename.text);
|
||||
filename.length = strlen(filename.text);
|
||||
|
||||
/* Initialize the pen and graphics screen. */
|
||||
startgraph(SCREENWIDTH); /* start QuickDraw II */
|
||||
SetPenSize(4, 2); /* use fatter pen */
|
||||
|
||||
/* Open the file and then write its contents to the graphics screen. */
|
||||
openDCB.pathname = &filename; /* open the file */
|
||||
OpenGS(&openDCB);
|
||||
if (i = toolerror()) {
|
||||
MoveTo(50, 100);
|
||||
SetSolidPenPat(black);
|
||||
sprintf(str, "Unable to open file for screen dump: err = %d\n", i);
|
||||
DrawCString(str);
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
readDCB.refNum = openDCB.refNum; /* read the file, sending */
|
||||
ReadGS(&readDCB); /* contents to screen */
|
||||
if (i = toolerror()) {
|
||||
MoveTo(50, 100);
|
||||
SetSolidPenPat(black);
|
||||
sprintf(str, "Unable to read file for screen dump: err = %d\n", i);
|
||||
DrawCString(str);
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
closeDCB.refNum = openDCB.refNum; /* close the file */
|
||||
CloseGS (&closeDCB);
|
||||
|
||||
/* Wrap up: Wait for user to signal end, then shut down tools started. */
|
||||
Fail:
|
||||
SetSolidPenPat(black); /* wait for user to signal end */
|
||||
str = "Press RETURN when ready to quit program";
|
||||
MoveTo(SCREENWIDTH-CStringWidth(str), 40);
|
||||
DrawCString(str);
|
||||
getchar(); getchar();
|
||||
endgraph();
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/*****************************************************************
|
||||
*
|
||||
* Call ProDOS 16
|
||||
*
|
||||
* This program draws ovals on the 16 color screen. It then
|
||||
* dumps the contents of the graphics screen to a file. If the
|
||||
* file is loaded and then stored to the graphics screen, the
|
||||
* image dumped is displayed.
|
||||
*
|
||||
* DO NOT EXECUTE THIS PROGRAM FROM THE DESKTOP. It uses non-
|
||||
* standard mechanisms for accessing the graphics screen.
|
||||
*
|
||||
* By Barbara Allred and Mike Westerfield
|
||||
*
|
||||
* Copyright 1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
#pragma keep "CallP16"
|
||||
#pragma debug 1 /* check stack overflows */
|
||||
|
||||
#include <prodos.h>
|
||||
|
||||
#pragma lint -1
|
||||
|
||||
#include <quickdraw.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <orca.h>
|
||||
|
||||
Rect ovalRect, *ovalPtr = &ovalRect; /* bounds rectangle for ovals */
|
||||
|
||||
/* Data Control Blocks for ProDOS 16 calls */
|
||||
FileRec createDCB = { NULL, 0x00E3, 0x06, 0, 0x01, 0, 0 };
|
||||
OpenRec openDCB;
|
||||
FileIORec writeDCB;
|
||||
|
||||
|
||||
int main (void)
|
||||
|
||||
{
|
||||
#define SCREENWIDTH 320 /* screen width in pixels */
|
||||
|
||||
int x = 40; /* horizontal location in global coords */
|
||||
int y = 20; /* vertical location in global coords */
|
||||
int color; /* initial pen color */
|
||||
char *str; /* work pointer */
|
||||
|
||||
char filename [L_tmpnam+1] = ""; /* name of file receiving screen dump */
|
||||
char *fn;
|
||||
|
||||
/* Start Quick Draw II */
|
||||
startgraph(SCREENWIDTH);
|
||||
SetPenSize(4, 2); /* use fatter pen */
|
||||
|
||||
/* Draw ovals in different colors on the screen. */
|
||||
for (color = 0; color < 15; color++) {
|
||||
ovalRect.v1 = x; ovalRect.h1 = y;
|
||||
ovalRect.v2 = x + 15; ovalRect.h2 = y + 15;
|
||||
SetSolidPenPat(color+1);
|
||||
MoveTo(y, x);
|
||||
PaintOval(ovalPtr);
|
||||
SetSolidPenPat(color);
|
||||
MoveTo(y, x);
|
||||
FrameOval(ovalPtr);
|
||||
if (toolerror()) {
|
||||
DrawCString("Failure in drawing routine\n");
|
||||
goto Fail;
|
||||
}
|
||||
y += 10; x += 10;
|
||||
}
|
||||
|
||||
/* Dump contents of screen to a file. */
|
||||
fn = tmpnam(&filename[1]); /* get unique filename for dump */
|
||||
if (fn == NULL) {
|
||||
MoveTo (100, 50);
|
||||
SetSolidPenPat(black);
|
||||
DrawCString("Unable to obtain unique filename for screen dump");
|
||||
goto Fail;
|
||||
}
|
||||
filename[0] = strlen(&filename[1]); /* convert C-string to P-string */
|
||||
|
||||
createDCB.pathname = filename; /* create screen dump file */
|
||||
CREATE(&createDCB);
|
||||
if (toolerror()) {
|
||||
MoveTo(50, 100);
|
||||
SetSolidPenPat(black);
|
||||
DrawCString("Unable to create file for screen dump");
|
||||
goto Fail;
|
||||
}
|
||||
openDCB.openPathname = filename; /* open the screen dump file */
|
||||
OPEN(&openDCB);
|
||||
if (toolerror()) {
|
||||
MoveTo(50, 100);
|
||||
SetSolidPenPat(black);
|
||||
DrawCString("Unable to open file for screen dump");
|
||||
goto Fail;
|
||||
}
|
||||
writeDCB.fileRefNum = openDCB.openRefNum; /* write screen contents to file */
|
||||
writeDCB.dataBuffer = (void *) 0x00E12000;
|
||||
writeDCB.requestCount = 32768L;
|
||||
WRITE(&writeDCB);
|
||||
if (toolerror()) {
|
||||
MoveTo(50, 100);
|
||||
SetSolidPenPat(black);
|
||||
DrawCString("Unable to write screen contents to file");
|
||||
goto Fail;
|
||||
}
|
||||
CLOSE(&openDCB); /* close the screen dump file */
|
||||
|
||||
/* Wrap up: Wait for key press and then shut down QuickDraw II. */
|
||||
Fail:
|
||||
SetSolidPenPat(black); /* wait for user to signal end */
|
||||
str = "Press return when ready to quit program";
|
||||
MoveTo(SCREENWIDTH-CStringWidth(str), 40);
|
||||
DrawCString(str);
|
||||
getchar();
|
||||
endgraph();
|
||||
printf("The name of the file containing the screen dump is:\n%b", filename);
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/****************************************************************
|
||||
*
|
||||
* Pipe
|
||||
*
|
||||
* A simple graphics demo.
|
||||
*
|
||||
* by Mike Westerfield
|
||||
*
|
||||
* Copyright 1987-1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
#pragma keep "Pipe"
|
||||
#pragma lint -1
|
||||
|
||||
#include <quickdraw.h>
|
||||
|
||||
#define xWidth 20
|
||||
#define yWidth 10
|
||||
|
||||
int main (void)
|
||||
|
||||
{
|
||||
Rect r; /* drawing rectangle */
|
||||
int x = xWidth; /* horizontal width of pipe */
|
||||
int y = yWidth; /* vertical width of pipe */
|
||||
int color = 1; /* pen color */
|
||||
int maxX; /* maximum horizontal pixel */
|
||||
int maxY; /* maximum vertical pixel */
|
||||
int minX; /* minimum horizontal pixel */
|
||||
int minY; /* minimum vertical pixel */
|
||||
int deltaX = 6; /* pipe width increment */
|
||||
int deltaY = 3; /* pipe depth increment */
|
||||
int i;
|
||||
|
||||
GetPortRect(&r); /* initialize drawing rectangle */
|
||||
maxX = r.h2 - xWidth; /* don't go beyond rect edges */
|
||||
maxY = r.v2 - yWidth;
|
||||
minX = r.v1;
|
||||
minY = r.h1;
|
||||
|
||||
for (i = 0; i < 150; ++i) { /* main loop: draw pipe, a series of ovals */
|
||||
r.h1 = x - xWidth;
|
||||
r.h2 = x + xWidth;
|
||||
r.v1 = y - yWidth;
|
||||
r.v2 = y + yWidth;
|
||||
color ^= 3;
|
||||
SetSolidPenPat(color);
|
||||
PaintOval(&r);
|
||||
SetSolidPenPat(0);
|
||||
FrameOval(&r);
|
||||
|
||||
x += deltaX; /* bend pipe as needed to fit within rectangle */
|
||||
if (x < xWidth) {
|
||||
x = xWidth;
|
||||
deltaX = -deltaX;
|
||||
}
|
||||
else if (x > maxX) {
|
||||
x = maxX;
|
||||
deltaX = -deltaX;
|
||||
}
|
||||
y += deltaY;
|
||||
if (y < yWidth) {
|
||||
y = yWidth;
|
||||
deltaY = -deltaY;
|
||||
}
|
||||
else if (y > maxY) {
|
||||
y = maxY;
|
||||
deltaY = -deltaY;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/****************************************************************
|
||||
*
|
||||
* Spiral
|
||||
*
|
||||
* A simple graphics demo. Uses the shell STOP command from the
|
||||
* debug menu to stop the program early.
|
||||
*
|
||||
* by Mike Westerfield
|
||||
*
|
||||
* Copyright 1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
#pragma keep "Spiral"
|
||||
#pragma lint -1
|
||||
|
||||
#include <quickdraw.h>
|
||||
#include <math.h>
|
||||
|
||||
int main (void)
|
||||
|
||||
{
|
||||
float r, theta, rot;
|
||||
int color = 1;
|
||||
Rect rect;
|
||||
|
||||
GetPortRect(&rect);
|
||||
SetPenSize(3, 1);
|
||||
for (rot = 0.0002; rot < 0.0005; rot += 0.0001) {
|
||||
theta = 0.0;
|
||||
r = 40.0;
|
||||
MoveTo ((int) (cos (theta) * r * 3) + 160,
|
||||
(int) (sin (theta) * r) + 40);
|
||||
while (r > 0.0) {
|
||||
SetSolidPenPat (color);
|
||||
color ^= 3;
|
||||
theta += 3.1415926535 / 21.0 + rot;
|
||||
LineTo ((int) (cos (theta) * r * 3) + 160,
|
||||
(int) (sin (theta) * r) + 40);
|
||||
r -= 0.02;
|
||||
}
|
||||
}
|
||||
Out: ;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*****************************************************************
|
||||
*
|
||||
* HyperCard XCMD
|
||||
*
|
||||
* This sample is a framework program, showing the essential parts
|
||||
* of a HyperCard XCMD.
|
||||
*
|
||||
* For complete details on the requirements for HyperCard XCMDs,
|
||||
* see the HyperCard technical documentation on the System 6.0
|
||||
* CD ROM.
|
||||
*
|
||||
* Build this program using the script xcmd.make. This script has
|
||||
* quite a few comments about the build process, so it's worth
|
||||
* loading the scrept and reading the comments.
|
||||
*
|
||||
* By Mike Westerfield
|
||||
*
|
||||
* Copyright 1993
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
*****************************************************************/
|
||||
|
||||
#pragma keep "xcmd"
|
||||
#pragma lint -1
|
||||
#pragma xcmd main
|
||||
|
||||
#include <HyperXCMD.h>
|
||||
#include <misctool.h>
|
||||
|
||||
void main (XCMDPtr parm)
|
||||
|
||||
{
|
||||
SysBeep();
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
*
|
||||
* This file builds the sample xcmd.cc.
|
||||
*
|
||||
|
||||
*
|
||||
* There's nothing special about the compile -- just be sure the program
|
||||
* itself uses the xcmd pragma, the small memory model, and does not use the
|
||||
* segment directive.
|
||||
*
|
||||
|
||||
compile xcmd.cc
|
||||
|
||||
*
|
||||
* The -x flag is crutial! XCMDs must consist of a single segment, and
|
||||
* without the -x flag on the link, the linker creates an expressload
|
||||
* segment.
|
||||
*
|
||||
|
||||
link -x xcmd keep=xcmd
|
||||
|
||||
*
|
||||
* The Rez compiler packs the executable code and a name into a file for
|
||||
* HyperCard.
|
||||
*
|
||||
|
||||
compile xcmd.rez keep=Beep
|
|
@ -0,0 +1,23 @@
|
|||
/*****************************************************************
|
||||
*
|
||||
* HyperCard XCMD
|
||||
*
|
||||
* This is the resource file for xcmd.cc.
|
||||
*
|
||||
* By Mike Westerfield
|
||||
*
|
||||
* Copyright 1993
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
*****************************************************************/
|
||||
|
||||
#include "types.rez"
|
||||
|
||||
read $801E(1, convert) "xcmd";
|
||||
|
||||
resource rResName ($0001801E) {
|
||||
1,
|
||||
{
|
||||
1, "Beep";
|
||||
}
|
||||
};
|
|
@ -0,0 +1,35 @@
|
|||
/*****************************************************************
|
||||
*
|
||||
* HyperStudio New Button Action (NBA)
|
||||
*
|
||||
* This sample is a framework program, showing the essential parts
|
||||
* of a HyperStudio NBA.
|
||||
*
|
||||
* For complete details on the requirements for HyperStudio NBAs,
|
||||
* contact Roger Wagner Publishing. When this sample was written,
|
||||
* details for writing HyperStudio NDAs were available in disk form
|
||||
* for $10.
|
||||
*
|
||||
* Build this program using the script xcmd.make. This script has
|
||||
* quite a few comments about the build process, so it's worth
|
||||
* loading the scrept and reading the comments.
|
||||
*
|
||||
* By Mike Westerfield
|
||||
*
|
||||
* Copyright 1993
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
*****************************************************************/
|
||||
|
||||
#pragma keep "nba"
|
||||
#pragma lint -1
|
||||
#pragma nba main
|
||||
|
||||
#include "HyperStudio.h"
|
||||
#include <misctool.h>
|
||||
|
||||
void main (HSParamPtr parm)
|
||||
|
||||
{
|
||||
SysBeep();
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
*
|
||||
* This file builds the sample nba.cc.
|
||||
*
|
||||
|
||||
*
|
||||
* There's nothing special about the compile -- just be sure the program
|
||||
* itself uses the nba pragma, the small memory model, and does not use the
|
||||
* segment directive.
|
||||
*
|
||||
|
||||
compile nba.cc
|
||||
|
||||
*
|
||||
* The -x flag is crutial! NBAs must consist of a single segment, and
|
||||
* without the -x flag on the link, the linker creates an expressload
|
||||
* segment.
|
||||
*
|
||||
|
||||
link -x nba keep=nba
|
||||
|
||||
*
|
||||
* The Rez compiler packs the executable code and a name into a file for
|
||||
* HyperStudio.
|
||||
*
|
||||
|
||||
compile nba.rez keep=Beep
|
||||
filetype Beep $BC $4007
|
|
@ -0,0 +1,23 @@
|
|||
/*****************************************************************
|
||||
*
|
||||
* HyperStudio NBA
|
||||
*
|
||||
* This is the resource file for nba.cc.
|
||||
*
|
||||
* By Mike Westerfield
|
||||
*
|
||||
* Copyright 1993
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
*****************************************************************/
|
||||
|
||||
#include "types.rez"
|
||||
|
||||
read $8017($7FF0, convert) "nba";
|
||||
|
||||
resource rResName ($00018017) {
|
||||
1,
|
||||
{
|
||||
$7FF0, "Beep";
|
||||
}
|
||||
};
|
|
@ -0,0 +1,67 @@
|
|||
/*****************************************************************
|
||||
*
|
||||
* Ackermann
|
||||
*
|
||||
* This program implements a famous mathematical function that
|
||||
* is often used to examine recursion. It is deceptively
|
||||
* simple, but can take enormous amounts of time and stack
|
||||
* space for relatively small arguments. For that reason,
|
||||
* rangechecking has been enabled to ensure the integrity of the
|
||||
* stack.
|
||||
*
|
||||
* By Mike Westerfield
|
||||
*
|
||||
* Copyright 1987-1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
*****************************************************************/
|
||||
|
||||
#pragma keep "Ackermann"
|
||||
#pragma debug 0x0001
|
||||
#pragma lint -1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Constants */
|
||||
#define maxm 2 /* max value of 1st argument */
|
||||
#define maxn 3 /* max value of 2nd argument */
|
||||
|
||||
/* Global variables */
|
||||
int a, m, n, depth, maxdepth;
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Ackermann - Demonstrates recursion in ORCA/C
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
int Ackermann (int m, int n)
|
||||
|
||||
{
|
||||
int result;
|
||||
|
||||
depth++;
|
||||
if (depth > maxdepth)
|
||||
maxdepth = depth;
|
||||
if (m == 0)
|
||||
return (n + 1);
|
||||
if (n == 0)
|
||||
return (Ackermann (m-1, 1));
|
||||
result = Ackermann (m-1, Ackermann (m, n-1));
|
||||
depth--;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int main (void)
|
||||
|
||||
{
|
||||
for (m = 0; m <= maxm; m++)
|
||||
for (n = 0; n <= maxn; n++) {
|
||||
depth = 0;
|
||||
maxdepth = 0;
|
||||
a = Ackermann (m, n);
|
||||
printf ("Ackermann(%d, %d) = %-4d ", m, n, a);
|
||||
printf ("Max recursion depth was %d\n", maxdepth);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/************************************************
|
||||
*
|
||||
* Artillery
|
||||
*
|
||||
* This classic interactive text game lets you
|
||||
* pick the angle of your artillery gun in
|
||||
* an attempt to knock out the enemy position.
|
||||
* The computer picks a secret distance. When
|
||||
* you fire, you will be told how much you
|
||||
* missed by, and must fire again. The object
|
||||
* is to hit the target with the fewest shells.
|
||||
*
|
||||
************************************************/
|
||||
|
||||
#pragma keep "Artillery"
|
||||
#pragma lint -1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <misctool.h>
|
||||
|
||||
#define FALSE 0 /* boolean constants */
|
||||
#define TRUE 1
|
||||
|
||||
#define BLASTRADIUS 50.0 /* max distance from target for a hit */
|
||||
#define DTR 0.01745329 /* convert from degrees to radians */
|
||||
#define VELOCITY 434.6 /* muzzle velocity */
|
||||
|
||||
int main(void)
|
||||
|
||||
{
|
||||
float angle, /* angle */
|
||||
distance, /* distance to the target */
|
||||
flightTime, /* time of flight */
|
||||
x, /* distance to impact */
|
||||
vx,vy; /* x, y velocities */
|
||||
int done, /* is there a hit, yet? */
|
||||
tries, /* number of shots */
|
||||
i; /* loop variable */
|
||||
|
||||
/* choose a distance to the target */
|
||||
srand((int) time(NULL));
|
||||
for (i = 0; i < 100; ++i)
|
||||
rand();
|
||||
distance = rand()/5.55373;
|
||||
|
||||
/* not done yet... */
|
||||
done = FALSE;
|
||||
tries = 1;
|
||||
|
||||
/* shoot 'til we hit it */
|
||||
do {
|
||||
/* get the firing angle */
|
||||
printf("Firing angle: ");
|
||||
scanf("%f", &angle);
|
||||
|
||||
/* compute the muzzle velocity in x, y */
|
||||
angle *= DTR;
|
||||
vx = cos(angle)*VELOCITY;
|
||||
vy = sin(angle)*VELOCITY;
|
||||
|
||||
/* find the time of flight */
|
||||
/* (velocity = acceleration*flightTime, two trips) */
|
||||
flightTime = 2.0*vy/32.0;
|
||||
|
||||
/* find the distance */
|
||||
/* (distance = velocity*flightTime) */
|
||||
x = vx*flightTime;
|
||||
|
||||
/* see what happened... */
|
||||
if (fabs(distance-x) < BLASTRADIUS) {
|
||||
done = TRUE;
|
||||
printf("A hit, after %d", tries);
|
||||
if (tries == 1)
|
||||
printf(" try!\n");
|
||||
else
|
||||
printf(" tries!\n");
|
||||
switch (tries) {
|
||||
case 1:
|
||||
printf("(A lucky shot...)\n");
|
||||
break;
|
||||
case 2:
|
||||
printf("Phenomenal shooting!\n");
|
||||
break;
|
||||
case 3:
|
||||
printf("Good shooting.\n");
|
||||
break;
|
||||
otherwise:
|
||||
printf("Practice makes perfect - try again.\n");
|
||||
}
|
||||
}
|
||||
else if (distance > x)
|
||||
printf("You were short by %d feet.\n", (int)(distance-x));
|
||||
else
|
||||
printf("You were over by %d feet.\n", (int)(x-distance));
|
||||
++tries;
|
||||
}
|
||||
while (!done);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/***************************************************************
|
||||
*
|
||||
* Command Line
|
||||
*
|
||||
* On the Apple IIgs, all EXE programs can expect three things
|
||||
* to be passed to them by the shell: a user ID number for use
|
||||
* with tool kits, an eight character shell ID which
|
||||
* identifies the shell that executed the program, and the
|
||||
* text from the command line itself. This program shows how
|
||||
* to access these values from C, printing them to the
|
||||
* screen. Be sure and execute the program with some text
|
||||
* after the name - for example,
|
||||
*
|
||||
* CLINE Hello, world.
|
||||
*
|
||||
* When any EXE program returns to the shell, it passes an
|
||||
* error code in the A register. You can set this value from
|
||||
* C by returning an integer value as the result of main, as
|
||||
* shown in this program.
|
||||
*
|
||||
* If you compile this program from the desktop, turn debug
|
||||
* code off before executing the program from the shell window.
|
||||
*
|
||||
***************************************************************/
|
||||
|
||||
#pragma keep "CLine"
|
||||
#pragma lint -1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <orca.h>
|
||||
|
||||
int main(void)
|
||||
|
||||
{
|
||||
char *shellName, *line;
|
||||
int userNumber;
|
||||
|
||||
userNumber = userid();
|
||||
shellName = shellid();
|
||||
line = commandline();
|
||||
printf("User ID: %d\n", userNumber);
|
||||
printf("Shell ID: %s\n", shellName);
|
||||
printf("Command line: %s\n", line);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*******************************************************************
|
||||
*
|
||||
* Error Exit
|
||||
*
|
||||
* You can call the library routines that handle run-time errors
|
||||
* from your own program. One of these, called strerror, will
|
||||
* print a text run-time error message to standard output. You
|
||||
* pass a single integer parameter, which is the run-time error
|
||||
* number. This procedure is generally called from an error trap
|
||||
* subroutine - see the sample program ERRORTRAP.CC for an example
|
||||
* of how to trap errors. In this program strerror is used to
|
||||
* list the current run-time error messages.
|
||||
*
|
||||
* The two built-in macros __FILE__ and __LINE__ are used to print
|
||||
* the current line number and the name of the current source file.
|
||||
*
|
||||
* The library subroutine SystemErrorLocation provides trace-back
|
||||
* information; it is further covered in the text sample program
|
||||
* ERRORTRAP.CC.
|
||||
*
|
||||
* By Mike Westerfield and Barbara Allred
|
||||
*
|
||||
* Copyright 1987-1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#pragma keep "ErrorExit"
|
||||
#pragma debug 8 /* enable trace-back of code */
|
||||
#pragma lint -1
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern pascal void SystemErrorLocation (void);
|
||||
/* A library procedure that prints the current location and a traceback. */
|
||||
|
||||
int main (void)
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
printf ("Run-time error messages are:\n\n");
|
||||
for (i = 1; i <= sys_nerr; i++)
|
||||
printf ("%3d: %s\n", i, strerror (i));
|
||||
|
||||
printf ("\nCurrent line: %d\nCurrent file: %s\n", __LINE__, __FILE__);
|
||||
|
||||
printf ("Exiting with a traceback.\n");
|
||||
SystemErrorLocation ();
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/******************************************************************
|
||||
*
|
||||
* Error Trap
|
||||
*
|
||||
* You can trap run-time errors with ORCA/C. There are several
|
||||
* reasons to do this, including:
|
||||
*
|
||||
* 1. Error messages take up space. By replacing the
|
||||
* system error handler with your own, you can cut
|
||||
* out the space needed to store the run-time error
|
||||
* messages.
|
||||
* 2. You may want to trap some kinds of run-time
|
||||
* errors, like file not found or out of memory,
|
||||
* and handle them yourself. If you do not, the
|
||||
* error will cause the program to stop executing,
|
||||
* which may not be the desired result.
|
||||
*
|
||||
* This program shows how to intercept and handle run-time
|
||||
* errors. This is done by placing a function in your program
|
||||
* called SYSTEMERROR. The function has a single parameter,
|
||||
* which is an integer error number. SYSTEMERROR replaces a
|
||||
* function by the same name that is normally linked in from
|
||||
* the libraries. Another library function, SystemErrorLocation,
|
||||
* provides the name of the function and the line number where
|
||||
* the run-time error occurred.
|
||||
*
|
||||
* Note that if you do not want to handle a particular error,
|
||||
* you can call the system error handlers from your program.
|
||||
* See the sample program ERROREXIT.CC for an example.
|
||||
*
|
||||
* By Mike Westerfield and Barbara Allred
|
||||
*
|
||||
* Copyright 1987-1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
#pragma keep "ErrorTrap"
|
||||
#pragma debug 9 /* enable range checking + trace-back */
|
||||
#pragma lint -1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
extern pascal void SystemErrorLocation (void);
|
||||
/* A library procedure that prints the current location and a traceback. */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* BadFunction - Subroutine that will generate a run-time error
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
static void BadFunction (void)
|
||||
|
||||
{
|
||||
char ch [8000]; /* this array is too large for */
|
||||
/* the default run-time stack */
|
||||
(void)ch; /* dummy use of ch to avoid lint msg */
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* DoIt - Calls function that will generate a run-time error
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
static void DoIt (void)
|
||||
{
|
||||
BadFunction(); /* call function with large array */
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* SystemError - Replaces SYSTEMERROR function in the ORCA library
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
static void SYSTEMERROR (int errorNumber)
|
||||
|
||||
{
|
||||
printf ("Run-time error detected. error number = %d\n", errorNumber);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Main program starts here
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
DoIt();
|
||||
SystemErrorLocation();
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/************************************************
|
||||
*
|
||||
* Finance
|
||||
*
|
||||
* This program prints the balance on an
|
||||
* account for monthly payments, along with the
|
||||
* total amount paid so far.
|
||||
*
|
||||
*************************************************/
|
||||
|
||||
#pragma keep "Finance"
|
||||
#pragma lint -1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define LOANAMOUNT 10000.0 /* amount of the loan */
|
||||
#define PAYMENT 600.0 /* monthly payment */
|
||||
#define INTEREST 15 /* yearly interest (as %) */
|
||||
|
||||
int main(void)
|
||||
|
||||
{
|
||||
float balance, /* amount left to pay */
|
||||
monthlyInterest, /* multiplier for interest */
|
||||
paid ; /* total amount paid */
|
||||
int month; /* month number */
|
||||
|
||||
/* set up the initial values */
|
||||
balance = LOANAMOUNT;
|
||||
paid = month = 0;
|
||||
monthlyInterest = 1.0 + INTEREST/1200.0;
|
||||
|
||||
/* write out the conditions */
|
||||
printf("Payment schedule for a loan of %10.2f\n", LOANAMOUNT);
|
||||
printf("with monthly payments of %5.2f at an\n", PAYMENT);
|
||||
printf("interest rate of %d%%.\n\n", INTEREST);
|
||||
printf(" month balance amount paid\n");
|
||||
printf(" ----- ------- -----------\n");
|
||||
|
||||
/* check for payments that are too small */
|
||||
if (balance*monthlyInterest - balance >= PAYMENT)
|
||||
printf("The payment is too small!");
|
||||
else
|
||||
while (balance > 0) {
|
||||
/* add in the interest */
|
||||
balance *= monthlyInterest;
|
||||
/* make a payment */
|
||||
if (balance > PAYMENT) {
|
||||
balance -= PAYMENT;
|
||||
paid += PAYMENT;
|
||||
}
|
||||
else {
|
||||
paid += balance;
|
||||
balance = 0;
|
||||
}
|
||||
/* update the month number */
|
||||
++month;
|
||||
/* write the new statistics */
|
||||
printf("%15d %14.2f %14.2f\n", month, balance, paid);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*****************************************************************
|
||||
*
|
||||
* Keyboard Handling
|
||||
*
|
||||
* This program shows one way to access the keyboard directly
|
||||
* from ORCA/C. Keep in mind that the standard file input
|
||||
* collects an entire line of characters before reporting the
|
||||
* first character. This is necessary to allow editing of the
|
||||
* input line. When using the desktop environment, you can get
|
||||
* keypress events from the event manager. This program shows
|
||||
* how to detect a keypress as soon as it is hit. It echoes
|
||||
* keys until you type CONTROL-@ (ASCII 0).
|
||||
*
|
||||
* The program works by reading the keyboard (at $C000) until
|
||||
* the value is negative, indicating that a key has been
|
||||
* pressed. It then stores a value (any value will do) in
|
||||
* $C010 to indicate that the key has been read. This makes
|
||||
* the value at $C010 positive (bit 7 is clear). The value of
|
||||
* the key is then ANDed with $7F to clear the high bit.
|
||||
*
|
||||
* THIS METHOD OF READING THE KEYBOARD ONLY WORKS IN THE TEXT
|
||||
* ENVIRONMENT. When the event manager is active, as it always
|
||||
* is in a desktop program, you should call the event manager
|
||||
* to read keystrokes.
|
||||
*
|
||||
* Checking to see when a key has been pressed is bundled into
|
||||
* the function KeyPress. Returning the key and clearing the
|
||||
* strobe is done in ReadChar.
|
||||
*
|
||||
* See key2 for a version that splits the keyboard routines off
|
||||
* into a separately compilable module.
|
||||
*
|
||||
* See key3 for a version that uses assembly language to do the
|
||||
* same thing.
|
||||
*
|
||||
* By Mike Westerfield and Barbara Allred
|
||||
*
|
||||
* Copyright 1987-1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
#pragma keep "Key"
|
||||
#pragma lint -1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static char ch; /* character read from keyboard */
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* KeyPress - Check if a key has been pressed
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
int KeyPress(void)
|
||||
|
||||
{
|
||||
char *keyboard;
|
||||
|
||||
keyboard = (char *) 0x00C000;
|
||||
return ((*keyboard) & 0x80) != 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* ReadChar - Return the last character typed on the keyboard.
|
||||
* Note: Returns a character whether or not one has
|
||||
* been typed!
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
char ReadChar (void)
|
||||
|
||||
{
|
||||
char *keyboard, *strobe;
|
||||
|
||||
keyboard = (char *) 0x00C000;
|
||||
strobe = (char *) 0x00C010;
|
||||
*strobe = 0;
|
||||
return *keyboard & 0x7F;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Main program starts here
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
int main(void)
|
||||
|
||||
{
|
||||
printf ("Press any key(s) and then RETURN. Enter CTRL-@ to quit.\n");
|
||||
do {
|
||||
while (! KeyPress()) /* wait for a keypress */
|
||||
;
|
||||
ch = ReadChar(); /* get character typed from keybrd */
|
||||
if (ch == 0x0D) /* write character to the screen */
|
||||
printf ("\n");
|
||||
else
|
||||
printf ("%c", ch);
|
||||
}
|
||||
while (ch != 0);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
unset exit
|
||||
echo compile key2.cc
|
||||
compile key2.cc
|
||||
if {status} == 0
|
||||
echo compile key2.funcs
|
||||
compile key2.funcs
|
||||
if {status} == 0
|
||||
echo link key2.cc key2.funcs
|
||||
link key2 funcs keep=Key2
|
||||
if {status} == 0
|
||||
key2
|
||||
else
|
||||
echo Unable to link key2.cc key2.funcs
|
||||
end
|
||||
else
|
||||
echo Unable to compile key2.funcs
|
||||
end
|
||||
else
|
||||
echo Unable to compile key2.cc
|
||||
end
|
|
@ -0,0 +1,43 @@
|
|||
/*****************************************************************
|
||||
*
|
||||
* This file contains the functions for KEY2.CC. See that file
|
||||
* for detailed comments.
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
#pragma keep "Funcs"
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* KeyPress - Check if a key has been pressed
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
int KeyPress(void)
|
||||
|
||||
{
|
||||
char *keyboard;
|
||||
|
||||
keyboard = (char *) 0x00C000;
|
||||
return ((*keyboard) & 0x80) != 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* ReadChar - Returns the last character typed on the keyboard.
|
||||
* Note: Returns a character whether or not one has
|
||||
* been typed!
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
char ReadChar(void)
|
||||
|
||||
{
|
||||
char *keyboard, *strobe;
|
||||
|
||||
keyboard = (char *) 0x00C000;
|
||||
strobe = (char *) 0x00C010;
|
||||
*strobe = 0;
|
||||
return *keyboard & 0x7F;
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*****************************************************************
|
||||
*
|
||||
* Keyboard Handling
|
||||
*
|
||||
* This program demonstrates separate compilation by splitting
|
||||
* the program KEY into two parts: the main program, and a
|
||||
* separately compiled file with the keyboard subroutines that
|
||||
* can then be called from many different programs without the
|
||||
* need for recompiling. See KEY.CC for a full description of
|
||||
* what this program does.
|
||||
*
|
||||
* The program now consists of four files:
|
||||
*
|
||||
* Key2.Build - EXEC file which separately compiles the two
|
||||
* source files, then links their object
|
||||
* modules to create the final program. To
|
||||
* use the EXEC file, simply type KEY2.BUILD
|
||||
* from the command line.
|
||||
*
|
||||
* Key2.cc - File containing main program.
|
||||
*
|
||||
* Key2.h - Header file accessed by the main program;
|
||||
* Contains declarations of external functions.
|
||||
*
|
||||
* Key2.Funcs - File containing keyboard functions called
|
||||
* by main program.
|
||||
*
|
||||
* See Key3 for a version that uses assembly language to read
|
||||
* the keyboard.
|
||||
*
|
||||
* By Mike Westerfield and Barbara Allred
|
||||
*
|
||||
* Copyright 1987-1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
#pragma keep "Key2"
|
||||
#pragma lint -1
|
||||
|
||||
#include "Key2.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
|
||||
{
|
||||
char ch;
|
||||
|
||||
printf ("Press any key(s) and then RETURN. Enter CTRL-@ to quit.\n");
|
||||
do {
|
||||
while (! KeyPress()) /* wait for a keypress */
|
||||
;
|
||||
ch = ReadChar(); /* get character typed from keybrd */
|
||||
if (ch == 0x0D) /* write character to the screen */
|
||||
printf ("\n");
|
||||
else
|
||||
printf ("%c", ch);
|
||||
}
|
||||
while (ch != 0);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
/* Header file for program Key2.CC */
|
||||
|
||||
extern int KeyPress(void);
|
||||
extern char ReadChar(void);
|
|
@ -0,0 +1,41 @@
|
|||
****************************************************************
|
||||
*
|
||||
* KeyPress - Check to see if a key has been pressed
|
||||
*
|
||||
* Outputs:
|
||||
* A - 1 (true) if pressed, else 0
|
||||
*
|
||||
****************************************************************
|
||||
*
|
||||
KeyPress start
|
||||
keyBoard equ $C000 keyboard location
|
||||
|
||||
sep #$30 use short regs for load
|
||||
lda >keyBoard load keyboard value
|
||||
asl A shift sign bit into bit 0
|
||||
rol A
|
||||
rep #$30 back to long regs
|
||||
and #1 and out all but the bit we want
|
||||
rtl
|
||||
end
|
||||
|
||||
****************************************************************
|
||||
*
|
||||
* ReadChar - return the last character typed on the keyboard
|
||||
*
|
||||
* Outputs:
|
||||
* A - character typed
|
||||
*
|
||||
****************************************************************
|
||||
*
|
||||
ReadChar start
|
||||
keyBoard equ $C000 keyboard location
|
||||
strobe equ $C010 strobe location
|
||||
|
||||
sep #$30 use short regs
|
||||
sta >strobe clear strobe
|
||||
lda >keyBoard load character
|
||||
rep #$30 back to long regs
|
||||
and #$007F and out high bits
|
||||
rtl
|
||||
end
|
|
@ -0,0 +1,64 @@
|
|||
/*****************************************************************
|
||||
*
|
||||
* Keyboard Handling
|
||||
*
|
||||
* This is the final incarnation of the keyboard polling sample.
|
||||
* See KEY.CC for complete comments on what the program does and
|
||||
* how it works.
|
||||
*
|
||||
* In this version, we will write the two subroutines in
|
||||
* assembly language. While you could use separate compilation
|
||||
* to compile and assemble the two pieces separately, then
|
||||
* link them, as in the last example, we will use chaining
|
||||
* to avoid all of that. Chaining is a feature of all
|
||||
* languages fully installed in ORCA or APW that allows a
|
||||
* single program to be written in more than one language
|
||||
* without resorting to separate compilation. Which method
|
||||
* you prefer - chaining or separate compilation - depends
|
||||
* on your own taste.
|
||||
*
|
||||
* To chain the two files together, we just place an append
|
||||
* command after the end of the program. The rest is automatic
|
||||
* To compile, assemble, link, and execute, we can now use the
|
||||
* familiar RUN command:
|
||||
*
|
||||
* run key3.cc
|
||||
*
|
||||
* Note: both the assembler and compiler must be properly
|
||||
* installed for this to work. The assembler is sold
|
||||
* separately as ORCA/M 2.0 for the Apple IIGS.
|
||||
*
|
||||
* By Mike Westerfield and Barbara Allred
|
||||
*
|
||||
* Copyright 1987-1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
*******************************************************************/
|
||||
|
||||
#pragma keep "Key3"
|
||||
#pragma lint -1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main (void)
|
||||
|
||||
{
|
||||
extern int KEYPRESS (void); /* declare assembly-language */
|
||||
extern int READCHAR (void); /* routines to be called */
|
||||
char ch; /* character read from keyboard */
|
||||
|
||||
printf("Press any key(s) and then RETURN. Enter CTRL-@ to quit.\n");
|
||||
do {
|
||||
while (! KEYPRESS()) /* wait for a keypress */
|
||||
;
|
||||
ch = READCHAR(); /* get character typed from keybrd */
|
||||
if (ch == 0x0D) /* write character to the screen */
|
||||
printf ("\n");
|
||||
else
|
||||
printf ("%c", ch);
|
||||
}
|
||||
while (ch != 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#append "Key3.asm"
|
|
@ -0,0 +1,34 @@
|
|||
/*****************************************************************
|
||||
*
|
||||
* Text Printer Demo
|
||||
*
|
||||
* This example shows how to access the .PRINTER text printer
|
||||
* driver from a C program. The .PRINTER driver must be installed
|
||||
* before this sample is executed.
|
||||
*
|
||||
* There really isn't much to this sample, which may seem bad at
|
||||
* first, but it's really good: accessing the text printer driver
|
||||
* really is as simple as opening the printer and writing to it!
|
||||
*
|
||||
* By Mike Westerfield
|
||||
*
|
||||
* Copyright 1993
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
*****************************************************************/
|
||||
|
||||
#pragma keep "Print"
|
||||
#pragma lint -1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void main (void)
|
||||
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
f = fopen(".printer", "w+");
|
||||
fprintf(f, "Hello, printer!\n");
|
||||
fputc('\f', f); /* on most printers, this will eject a page */
|
||||
fclose(f);
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/****************************************************************
|
||||
*
|
||||
* Trace
|
||||
*
|
||||
* ORCA/C can give you a traceback when a run-time error occurs.
|
||||
* A traceback shows the function and line number where the
|
||||
* error occurred, then gives a list of functions and line
|
||||
* numbers that show what subroutine calls were made to get to
|
||||
* the point where the error occurred. This program illustrates
|
||||
* this by deliberately failing in the function named Fail.
|
||||
*
|
||||
* By Mike Westerfield and Barbara Allred
|
||||
*
|
||||
* Copyright 1987-1989
|
||||
* Byte Works, Inc.
|
||||
*
|
||||
******************************************************************/
|
||||
|
||||
#pragma keep "Trace"
|
||||
#pragma debug 9
|
||||
#pragma lint -1
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Fail - Subroutine that will generate a run-time error
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
static void Fail (void)
|
||||
{
|
||||
char ch [8000]; /* this array is too large for */
|
||||
/* the default run-time stack */
|
||||
(void)ch; /* dummy use of ch to avoid lint msg */
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* DoIt - Calls subroutine that will generate a run-time error
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
static void DoIt (void)
|
||||
|
||||
{
|
||||
Fail();
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* Main program starts here
|
||||
*
|
||||
****************************************************************/
|
||||
|
||||
int main (void)
|
||||
|
||||
{
|
||||
printf ("This program fails. Generating a traceback:\n");
|
||||
DoIt();
|
||||
}
|
|
@ -1,15 +1,25 @@
|
|||
Welcome to ORCA/C 2.2.0 B7! This is an update release containing
|
||||
patches from community members (Stephen Heumann and Kelvin Sherlock),
|
||||
which add new features and fix bugs. For details on these changes,
|
||||
see the cc.notes file in the Release.Notes directory.
|
||||
This is an update package that can be used to update ORCA/C 2.1.0 or
|
||||
2.2.0 to ORCA/C 2.2.1. You must have an existing copy of ORCA/C 2.1.0
|
||||
or 2.2.0 in order to use this update. If you do not already have a
|
||||
copy, you can get it as part of Opus ][: The Software, a collection of
|
||||
Byte Works software which is sold by Juiced.GS:
|
||||
https://juiced.gs/store/opus-ii-software/
|
||||
|
||||
This package is designed to be applied as an update to an existing
|
||||
ORCA installation containing ORCA/C 2.1.0 or later (including the one
|
||||
provided on Opus ][: The Software). To apply the update, simply copy
|
||||
the files from this distribution into the corresponding locations in
|
||||
your ORCA installation, replacing any older versions. (One easy way
|
||||
to do this is to extract the archive containing this update directly
|
||||
on top of your ORCA installation, overwriting all modified files.)
|
||||
This update must be applied to an existing ORCA installation containing
|
||||
ORCA/C 2.1.0 or ORCA/C 2.2.0 (including the one provided on Opus ][:
|
||||
The Software). To apply the update, you just need to copy the files
|
||||
from this distribution into the corresponding locations in your ORCA
|
||||
installation, replacing any older versions.
|
||||
|
||||
If you received this update as a SHK file, you can simply extract the
|
||||
files from it directly on top of your ORCA installation.
|
||||
|
||||
If you received this update as a disk image, you can apply the update
|
||||
by copying the files into place using the Finder, or by running the
|
||||
following command within the root directory of your ORCA installation
|
||||
using the text-based ORCA shell:
|
||||
|
||||
COPY -C :ORCAC.221:=
|
||||
|
||||
In addition to the ORCA shell environment, this update can also be
|
||||
used under other environments that are compatible with ORCA/C, such as
|
||||
|
@ -18,20 +28,3 @@ into the directory containing files from a standard ORCA installation
|
|||
(normally /lang/orca for GNO). An updated version of ORCALib suitable
|
||||
for use under GNO is available as a separate download at:
|
||||
https://github.com/byteworksinc/ORCALib/releases
|
||||
|
||||
If you have any questions, or if you want to get involved in ORCA/C
|
||||
development, please get in touch. The ORCA/C development project is
|
||||
hosted on GitHub, and bug reports or patches can be submitted there:
|
||||
https://github.com/byteworksinc/ORCA-C
|
||||
|
||||
Thanks to:
|
||||
* Mike Westerfield, for writing ORCA/C, releasing the source code,
|
||||
and permitting it to be updated by the community.
|
||||
* Kelvin Sherlock, for providing several patches and bug reports, and
|
||||
for writing several useful tools for modern Apple II development.
|
||||
* Soenke Behrens, for compiling a list of ORCA/C bug reports and test
|
||||
cases, which has helped me to identify and fix a number of bugs.
|
||||
* The developers of Csmith (http://embed.cs.utah.edu/csmith/), an
|
||||
automated compiler testing tool that has helped to find several bugs.
|
||||
|
||||
--Stephen Heumann (stephenheumann@gmail.com)
|
||||
|
|
8
CC.rez
8
CC.rez
|
@ -4,12 +4,12 @@ resource rVersion(1) {
|
|||
{
|
||||
2, /* Major revision */
|
||||
2, /* Minor revision */
|
||||
0, /* Bug version */
|
||||
beta, /* Release stage */
|
||||
7, /* Non-final release # */
|
||||
1, /* Bug version */
|
||||
development, /* Release stage */
|
||||
1, /* Non-final release # */
|
||||
},
|
||||
verUS, /* Region code */
|
||||
"ORCA/C", /* Short version number */
|
||||
"Copyright 1997, Byte Works, Inc.\n" /* Long version number */
|
||||
"Updated 2023"
|
||||
"Updated 2024"
|
||||
};
|
||||
|
|
|
@ -112,7 +112,7 @@ const
|
|||
flag_t = $00001000; {treat all errors as terminal?}
|
||||
flag_w = $00000200; {wait when an error is found?}
|
||||
|
||||
versionStr = '2.2.0 B7'; {compiler version}
|
||||
versionStr = '2.2.1 dev'; {compiler version}
|
||||
|
||||
type
|
||||
{Misc.}
|
||||
|
@ -202,6 +202,7 @@ type
|
|||
barbarop,pluseqop,minuseqop,asteriskeqop,slasheqop,
|
||||
percenteqop,ltlteqop,gtgteqop,andeqop,caroteqop,
|
||||
bareqop,poundpoundop,dotdotdotsy,
|
||||
ppnumber, {preprocessing number (pp-token)}
|
||||
otherch, {other non-whitespace char (pp-token)}
|
||||
eolsy,eofsy, {control characters}
|
||||
typedef, {user types}
|
||||
|
@ -225,7 +226,7 @@ type
|
|||
tokenSet = set of tokenEnum;
|
||||
tokenClass = (reservedWord,reservedSymbol,identifier,intConstant,longConstant,
|
||||
longlongConstant,realConstant,stringConstant,otherCharacter,
|
||||
macroParameter);
|
||||
preprocessingNumber,macroParameter);
|
||||
identPtr = ^identRecord; {^ to a symbol table entry}
|
||||
tokenType = record {a token}
|
||||
kind: tokenEnum; {kind of token}
|
||||
|
@ -243,6 +244,7 @@ type
|
|||
ispstring: boolean;
|
||||
prefix: charStrPrefixEnum);
|
||||
otherCharacter: (ch: char); {used for preprocessing tokens only}
|
||||
preprocessingNumber: (errCode: integer); {used for pp tokens only}
|
||||
macroParameter: (pnum: integer);
|
||||
end;
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ opt[pc_ckn] := 'ckn';
|
|||
end; {InitWriteCode}
|
||||
|
||||
|
||||
procedure PrintDAG (tag: stringPtr; code: icptr);
|
||||
procedure PrintDAG {tag: stringPtr; code: icptr};
|
||||
|
||||
{ print a DAG }
|
||||
{ }
|
||||
|
|
108
CGI.pas
108
CGI.pas
|
@ -48,6 +48,7 @@ const
|
|||
forFlags = 256; {instruction used for effect on flags only}
|
||||
subtract1 = 512; {subtract 1 from address operand}
|
||||
shiftLeft8 = 1024; {shift operand left 8 bits}
|
||||
labelUsedOnce = 2048; {only one branch targets this label}
|
||||
|
||||
m_adc_abs = $6D; {op code #s for 65816 instructions}
|
||||
m_adc_dir = $65;
|
||||
|
@ -292,6 +293,8 @@ type
|
|||
ccPointer : (pval: longint; pstr: longStringPtr);
|
||||
end;
|
||||
|
||||
codeRef = icptr; {reference to a code location}
|
||||
|
||||
{basic blocks}
|
||||
{------------}
|
||||
iclist = ^iclistRecord; {used to form lists of records}
|
||||
|
@ -657,6 +660,21 @@ procedure GenTool (fop: pcodes; fp1, fp2: integer; dispatcher: longint);
|
|||
{ dispatcher - tool entry point }
|
||||
|
||||
|
||||
function GetCodeLocation: codeRef;
|
||||
|
||||
{ Get a reference to the current location in the generated }
|
||||
{ code, suitable to be passed to RemoveCode. }
|
||||
|
||||
|
||||
procedure InsertCode (theCode: codeRef);
|
||||
|
||||
{ Insert a section of already-generated code that was }
|
||||
{ previously removed with RemoveCode. }
|
||||
{ }
|
||||
{ parameters: }
|
||||
{ theCode - code removed (returned from RemoveCode) }
|
||||
|
||||
|
||||
{procedure PrintBlocks (tag: stringPtr; bp: blockPtr); {debug}
|
||||
|
||||
{ print a series of basic blocks }
|
||||
|
@ -666,6 +684,28 @@ procedure GenTool (fop: pcodes; fp1, fp2: integer; dispatcher: longint);
|
|||
{ bp - first block to print }
|
||||
|
||||
|
||||
{procedure PrintDAG (tag: stringPtr; code: icptr); {debug}
|
||||
|
||||
{ print a DAG }
|
||||
{ }
|
||||
{ parameters: }
|
||||
{ tag - label for lines }
|
||||
{ code - first node in DAG }
|
||||
|
||||
|
||||
function RemoveCode (start: codeRef): codeRef;
|
||||
|
||||
{ Remove a section of already-generated code, from immediately }
|
||||
{ after start up to the latest code generated. Returns the }
|
||||
{ code removed, so it may be re-inserted later. }
|
||||
{ }
|
||||
{ parameters: }
|
||||
{ start - location to start removing from }
|
||||
{ }
|
||||
{ Note: start must be a top-level pcode (not a subexpression). }
|
||||
{ Note: The region removed must not include a dc_enp. }
|
||||
|
||||
|
||||
function TypeSize (tp: baseTypeEnum): integer;
|
||||
|
||||
{ Find the size, in bytes, of a variable }
|
||||
|
@ -1430,6 +1470,74 @@ if codeGeneration then begin
|
|||
end; {GenLdcReal}
|
||||
|
||||
|
||||
function GetCodeLocation{: codeRef};
|
||||
|
||||
{ Get a reference to the current location in the generated }
|
||||
{ code, suitable to be passed to RemoveCode. }
|
||||
|
||||
begin {GetCodeLocation}
|
||||
GetCodeLocation := DAGhead;
|
||||
end {GetCodeLocation};
|
||||
|
||||
|
||||
procedure InsertCode {theCode: codeRef};
|
||||
|
||||
{ Insert a section of already-generated code that was }
|
||||
{ previously removed with RemoveCode. }
|
||||
{ }
|
||||
{ parameters: }
|
||||
{ theCode - code removed (returned from RemoveCode) }
|
||||
|
||||
var
|
||||
lcode: icptr;
|
||||
|
||||
begin {InsertCode}
|
||||
if theCode <> nil then
|
||||
if codeGeneration then begin
|
||||
lcode := theCode;
|
||||
{ PrintDAG(@'Inserting: ', lcode); {debug}
|
||||
while lcode^.next <> nil do
|
||||
lcode := lcode^.next;
|
||||
lcode^.next := DAGhead;
|
||||
DAGhead := theCode;
|
||||
end; {if}
|
||||
end; {InsertCode}
|
||||
|
||||
|
||||
function RemoveCode {start: codeRef): codeRef};
|
||||
|
||||
{ Remove a section of already-generated code, from immediately }
|
||||
{ after start up to the latest code generated. Returns the }
|
||||
{ code removed, so it may be re-inserted later. }
|
||||
{ }
|
||||
{ parameters: }
|
||||
{ start - location to start removing from }
|
||||
{ }
|
||||
{ Note: start must be a top-level pcode (not a subexpression). }
|
||||
{ Note: The region removed must not include a dc_enp. }
|
||||
|
||||
var
|
||||
lcode: icptr;
|
||||
|
||||
begin {RemoveCode}
|
||||
if start = DAGhead then
|
||||
RemoveCode := nil
|
||||
else begin
|
||||
RemoveCode := DAGhead;
|
||||
if codeGeneration then begin
|
||||
lcode := DAGhead;
|
||||
while (lcode^.next <> start) and (lcode^.next <> nil) do
|
||||
lcode := lcode^.next;
|
||||
if lcode^.next = nil then
|
||||
Error(cge1);
|
||||
lcode^.next := nil;
|
||||
{ PrintDAG(@'Removing: ', DAGhead); {debug}
|
||||
DAGhead := start;
|
||||
end; {if}
|
||||
end; {else}
|
||||
end; {RemoveCode}
|
||||
|
||||
|
||||
function TypeSize {tp: baseTypeEnum): integer};
|
||||
|
||||
{ Find the size, in bytes, of a variable }
|
||||
|
|
19
DAG.pas
19
DAG.pas
|
@ -565,6 +565,12 @@ var
|
|||
false: (rval: real);
|
||||
end;
|
||||
|
||||
cnvdbl: record {for stuffing a double in a quad space}
|
||||
case boolean of
|
||||
true: (qval: longlong);
|
||||
false: (rval: double);
|
||||
end;
|
||||
|
||||
begin {RealStoreOptimizations}
|
||||
if opl^.opcode = pc_cnv then
|
||||
if baseTypeEnum(opl^.q & $000F) = op^.optype then
|
||||
|
@ -631,6 +637,19 @@ var
|
|||
opl^.optype := cgLong;
|
||||
op^.optype := cgLong;
|
||||
end; {if}
|
||||
end {if}
|
||||
else if op^.optype = cgDouble then begin
|
||||
if opl^.opcode = pc_ldc then begin
|
||||
cnvdbl.rval := opl^.rval;
|
||||
opl^.qval := cnvdbl.qval;
|
||||
opl^.optype := cgQuad;
|
||||
op^.optype := cgQuad;
|
||||
end {if}
|
||||
else if opl^.opcode in [pc_ind,pc_ldo,pc_lod] then
|
||||
if opl^.optype = cgDouble then begin
|
||||
opl^.optype := cgQuad;
|
||||
op^.optype := cgQuad;
|
||||
end; {if}
|
||||
end; {if}
|
||||
end; {RealStoreOptimizations}
|
||||
|
||||
|
|
|
@ -1414,7 +1414,11 @@ var
|
|||
op1 := op1 * op2;
|
||||
slashch : begin {/}
|
||||
if op2 = 0 then begin
|
||||
Error(109);
|
||||
if not (kind in [normalExpression,
|
||||
autoInitializerExpression]) then
|
||||
Error(109)
|
||||
else if ((lint & lintOverflow) <> 0) then
|
||||
Error(129);
|
||||
op2 := 1;
|
||||
end; {if}
|
||||
if unsigned then
|
||||
|
@ -1424,7 +1428,11 @@ var
|
|||
end;
|
||||
percentch : begin {%}
|
||||
if op2 = 0 then begin
|
||||
Error(109);
|
||||
if not (kind in [normalExpression,
|
||||
autoInitializerExpression]) then
|
||||
Error(109)
|
||||
else if ((lint & lintOverflow) <> 0) then
|
||||
Error(129);
|
||||
op2 := 1;
|
||||
end; {if}
|
||||
if unsigned then
|
||||
|
@ -1570,7 +1578,11 @@ var
|
|||
asteriskch : umul64(llop1, llop2); {*}
|
||||
slashch : begin {/}
|
||||
if (llop2.lo = 0) and (llop2.hi = 0) then begin
|
||||
Error(109);
|
||||
if not (kind in [normalExpression,
|
||||
autoInitializerExpression]) then
|
||||
Error(109)
|
||||
else if ((lint & lintOverflow) <> 0) then
|
||||
Error(129);
|
||||
llop2 := longlong1;
|
||||
end; {if}
|
||||
if unsigned then
|
||||
|
@ -1580,7 +1592,11 @@ var
|
|||
end;
|
||||
percentch : begin {%}
|
||||
if (llop2.lo = 0) and (llop2.hi = 0) then begin
|
||||
Error(109);
|
||||
if not (kind in [normalExpression,
|
||||
autoInitializerExpression]) then
|
||||
Error(109)
|
||||
else if ((lint & lintOverflow) <> 0) then
|
||||
Error(129);
|
||||
llop2 := longlong1;
|
||||
end; {if}
|
||||
if unsigned then
|
||||
|
@ -1712,12 +1728,16 @@ var
|
|||
if op^.token.kind = sizeofsy then begin
|
||||
op^.token.kind := ulongConst;
|
||||
op^.token.class := longConstant;
|
||||
if op^.left^.token.kind = stringConst then
|
||||
kindLeft := op^.left^.token.kind;
|
||||
if kindLeft = stringConst then
|
||||
op^.token.lval := op^.left^.token.sval^.length
|
||||
else begin
|
||||
lCodeGeneration := codeGeneration;
|
||||
codeGeneration := false;
|
||||
GenerateCode(op^.left);
|
||||
if kindLeft = dotch then
|
||||
if isBitfield then
|
||||
Error(49);
|
||||
codeGeneration := lCodeGeneration and (numErrors = 0);
|
||||
op^.token.lval := expressionType^.size;
|
||||
with expressionType^ do
|
||||
|
@ -3294,8 +3314,10 @@ var
|
|||
else
|
||||
Gen2t(pc_ind, ord(tqVolatile in expressionType^.qualifiers), 0, tp);
|
||||
if pc_l in [pc_lli,pc_lld] then
|
||||
if expressionType^.cType in [ctBool,ctFloat,ctDouble,ctLongDouble,
|
||||
ctComp] then begin
|
||||
if (expressionType^.kind = scalarType) and
|
||||
(expressionType^.cType in
|
||||
[ctBool,ctFloat,ctDouble,ctLongDouble,ctComp])
|
||||
then begin
|
||||
t1 := GetTemp(ord(expressionType^.size));
|
||||
Gen2t(pc_cop, t1, 0, expressionType^.baseType);
|
||||
end; {if}
|
||||
|
@ -3306,8 +3328,10 @@ var
|
|||
Gen0t(pc_cpi, tp);
|
||||
Gen0t(pc_bno, tp);
|
||||
if pc_l in [pc_lli,pc_lld] then {correct the value for postfix ops}
|
||||
if expressionType^.cType in [ctBool,ctFloat,ctDouble,ctLongDouble,
|
||||
ctComp] then begin
|
||||
if (expressionType^.kind = scalarType) and
|
||||
(expressionType^.cType in
|
||||
[ctBool,ctFloat,ctDouble,ctLongDouble,ctComp])
|
||||
then begin
|
||||
Gen0t(pc_pop, expressionType^.baseType);
|
||||
Gen2t(pc_lod, t1, 0, expressionType^.baseType);
|
||||
Gen0t(pc_bno, expressionType^.baseType);
|
||||
|
@ -3429,11 +3453,17 @@ var
|
|||
while tp <> nil do begin
|
||||
if tp^.middle <> nil then begin
|
||||
GenerateCode(tp^.middle);
|
||||
if expressionType^.kind in [structType,unionType] then begin
|
||||
if expressionType^.size & $FFFF8000 <> 0 then
|
||||
Error(61);
|
||||
Gen1t(pc_ldc, long(expressionType^.size).lsw, cgWord);
|
||||
Gen0(pc_psh);
|
||||
if expressionType^.kind in [structType,unionType,definedType]
|
||||
then begin
|
||||
tType := expressionType;
|
||||
while tType^.kind = definedType do
|
||||
tType := tType^.dType;
|
||||
if tType^.kind in [structType,unionType] then begin
|
||||
if tType^.size & $FFFF8000 <> 0 then
|
||||
Error(61);
|
||||
Gen1t(pc_ldc, long(tType^.size).lsw, cgWord);
|
||||
Gen0(pc_psh);
|
||||
end; {if}
|
||||
end; {if}
|
||||
if fmt <> fmt_none then begin
|
||||
new(tfp);
|
||||
|
@ -4690,6 +4720,7 @@ case tree^.token.kind of
|
|||
|
||||
dotch: begin {.}
|
||||
LoadAddress(tree^.left, checkNullPointers);
|
||||
isBitfield := false;
|
||||
lType := expressionType;
|
||||
if lType^.kind in [arrayType,pointerType,structType,unionType] then begin
|
||||
if lType^.kind = arrayType then
|
||||
|
|
525
Gen.pas
525
Gen.pas
|
@ -321,6 +321,7 @@ case op^.opcode of
|
|||
loc := LabelToDisp(op^.left^.r) + op^.left^.q;
|
||||
if (op^.left^.opcode <> pc_lod) or (loc > 255) then
|
||||
Error(cge1);
|
||||
offset := offset + op^.q;
|
||||
if offset = 0 then
|
||||
GenNative(mop, direct, loc, nil, 0)
|
||||
else begin
|
||||
|
@ -618,7 +619,7 @@ function NeedsCondition (opcode: pcodes): boolean;
|
|||
|
||||
begin {NeedsCondition}
|
||||
NeedsCondition := opcode in
|
||||
[pc_and,pc_ior,pc_cui,pc_cup,pc_lor,pc_lnd,pc_ldl,pc_lil,pc_lld,
|
||||
[pc_and,pc_ior,pc_cui,pc_cup,pc_ldl,pc_lil,pc_lld,
|
||||
pc_lli,pc_gil,pc_gli,pc_gdl,pc_gld,pc_iil,pc_ili,pc_idl,pc_ild,
|
||||
pc_cop,pc_cpo,pc_cpi,pc_dvi,pc_mpi,pc_adi,pc_sbi,pc_mod,pc_bno,
|
||||
pc_udi,pc_uim,pc_umi,pc_cnv,pc_rbo,pc_shl,pc_shr,pc_usr,pc_lbf,
|
||||
|
@ -1068,8 +1069,22 @@ var
|
|||
end; {ReverseConditional}
|
||||
|
||||
|
||||
function SimpleLongOp(op: icptr): boolean;
|
||||
|
||||
{ Is op an operation on cg(U)Long that can be done using the }
|
||||
{ addressing modes of CPX? }
|
||||
|
||||
begin {SimpleLongOp}
|
||||
SimpleLongOp :=
|
||||
(op^.opcode = pc_ldc)
|
||||
or (op^.opcode = pc_lao)
|
||||
or ((op^.opcode = pc_lod) and (LabelToDisp(op^.r) + op^.q <= 253))
|
||||
or ((op^.opcode = pc_ldo) and smallMemoryModel);
|
||||
end; {SimpleLongOp}
|
||||
|
||||
|
||||
begin {GenCmp}
|
||||
{To reduct the number of possibilities that must be handled, pc_les }
|
||||
{To reduce the number of possibilities that must be handled, pc_les }
|
||||
{and pc_leq compares are reduced to their equivalent pc_grt and }
|
||||
{pc_geq instructions. }
|
||||
if op^.opcode = pc_les then begin
|
||||
|
@ -1113,15 +1128,16 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
|||
if NeedsCondition(op^.left^.opcode) then
|
||||
GenImpliedForFlags(m_tax);
|
||||
if (num >= 0) and (num < 3) then begin
|
||||
if num <> 0 then begin
|
||||
if num = 0 then
|
||||
GenNative(m_bpl, relative, lab1, nil, 0)
|
||||
else begin
|
||||
lab2 := GenLabel;
|
||||
GenNative(m_bmi, relative, lab2, nil, 0);
|
||||
for i := 1 to num do
|
||||
GenImplied(m_dea);
|
||||
end; {if}
|
||||
GenNative(m_bpl, relative, lab1, nil, 0);
|
||||
if num <> 0 then
|
||||
GenLab(lab2);
|
||||
if num = 2 then
|
||||
GenImplied(m_lsr_a);
|
||||
GenNative(m_bne, relative, lab1, nil, 0);
|
||||
GenLabUsedOnce(lab2);
|
||||
end; {else}
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab1);
|
||||
end {if (num >= 0) and (num < 3)}
|
||||
|
@ -1134,7 +1150,7 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
|||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
GenNative(m_bcs, relative, lab2, nil, 0);
|
||||
if num > 0 then begin
|
||||
GenLab(lab1);
|
||||
GenLabUsedOnce(lab1);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab2);
|
||||
end {if}
|
||||
|
@ -1147,8 +1163,17 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
|||
end {if}
|
||||
else {if optype in [cgUByte,cgUWord] then} begin
|
||||
if num <> 0 then begin
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
GenNative(m_bcs, relative, lab1, nil, 0);
|
||||
if num in [1,2] then begin
|
||||
if num = 1 then
|
||||
GenImpliedForFlags(m_tax)
|
||||
else
|
||||
GenImplied(m_lsr_a);
|
||||
GenNative(m_bne, relative, lab1, nil, 0);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
GenNative(m_bcs, relative, lab1, nil, 0);
|
||||
end; {else}
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {if}
|
||||
|
@ -1163,9 +1188,9 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
|||
if (num >= 0) and (num < 3) then begin
|
||||
GenNative(m_bmi, relative, lab1, nil, 0);
|
||||
if num > 0 then begin
|
||||
for i := 1 to num do
|
||||
GenImplied(m_dea);
|
||||
GenNative(m_bmi, relative, lab1, nil, 0);
|
||||
if num = 2 then
|
||||
GenImplied(m_lsr_a);
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
end; {if}
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab1);
|
||||
|
@ -1184,7 +1209,7 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
|||
GenLab(lab1);
|
||||
end {if}
|
||||
else begin
|
||||
GenLab(lab1);
|
||||
GenLabUsedOnce(lab1);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab2);
|
||||
end; {else}
|
||||
|
@ -1192,8 +1217,17 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
|||
end {if}
|
||||
else {if optype in [cgUByte,cgUWord] then} begin
|
||||
if num <> 0 then begin
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
GenNative(m_bcc, relative, lab1, nil, 0);
|
||||
if num in [1,2] then begin
|
||||
if num = 1 then
|
||||
GenImpliedForFlags(m_tax)
|
||||
else
|
||||
GenImplied(m_lsr_a);
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
GenNative(m_bcc, relative, lab1, nil, 0);
|
||||
end; {else}
|
||||
end; {if}
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
if num <> 0 then
|
||||
|
@ -1282,7 +1316,7 @@ else
|
|||
else
|
||||
GenNative(m_bcs, relative, lab2, nil, 0);
|
||||
if op^.opcode = pc_grt then
|
||||
GenLab(lab3);
|
||||
GenLabUsedOnce(lab3);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab2);
|
||||
end {if}
|
||||
|
@ -1330,50 +1364,134 @@ else
|
|||
end; {case optype of cgByte,cgUByte,cgWord,cgUWord}
|
||||
|
||||
cgULong: begin
|
||||
gLong.preference := onStack;
|
||||
GenTree(op^.right);
|
||||
gLong.preference := A_X;
|
||||
GenTree(op^.left);
|
||||
if gLong.where = onStack then begin
|
||||
GenImplied(m_ply);
|
||||
GenImplied(m_pla);
|
||||
lab1 := GenLabel;
|
||||
lab2 := GenLabel;
|
||||
simple := false;
|
||||
if SimpleLongOp(op^.right) then
|
||||
simple := true
|
||||
else if rOpcode in [pc_fjp,pc_tjp] then
|
||||
if SimpleLongOp(op^.left) then begin
|
||||
ReverseConditional;
|
||||
simple := true;
|
||||
end; {if}
|
||||
if simple then begin
|
||||
if op^.opcode = pc_grt then begin
|
||||
if SimpleLongOp(op^.left) then
|
||||
ReverseConditional;
|
||||
if op^.opcode = pc_grt then
|
||||
if op^.right^.opcode = pc_ldc then
|
||||
if op^.right^.lval <> $ffffffff then begin
|
||||
op^.right^.lval := op^.right^.lval + 1;
|
||||
op^.opcode := pc_geq;
|
||||
end; {if}
|
||||
end; {if}
|
||||
gLong.preference := A_X;
|
||||
GenTree(op^.left);
|
||||
if gLong.where = onStack then begin
|
||||
GenImplied(m_pla);
|
||||
GenImplied(m_plx);
|
||||
end; {if}
|
||||
if op^.opcode = pc_grt then
|
||||
if not (rOpcode in [pc_fjp,pc_tjp]) then
|
||||
GenNative(m_ldy_imm, immediate, 0, nil, 0);
|
||||
with op^.right^ do
|
||||
case opcode of
|
||||
pc_ldc:
|
||||
GenNative(m_cpx_imm, immediate, long(lval).msw, nil, 0);
|
||||
pc_lao:
|
||||
GenNative(m_cpx_imm, immediate, q, lab, shift16);
|
||||
pc_lod:
|
||||
GenNative(m_cpx_dir, direct, LabelToDisp(r)+q+2, nil, 0);
|
||||
pc_ldo:
|
||||
GenNative(m_cpx_abs, absolute, q+2, lab, 0);
|
||||
end; {case}
|
||||
GenNative(m_bne, relative, lab1, nil, 0);
|
||||
with op^.right^ do
|
||||
case opcode of
|
||||
pc_ldc:
|
||||
GenNative(m_cmp_imm, immediate, long(lval).lsw, nil, 0);
|
||||
pc_lao:
|
||||
GenNative(m_cmp_imm, immediate, q, lab, 0);
|
||||
pc_lod:
|
||||
GenNative(m_cmp_dir, direct, LabelToDisp(r)+q, nil, 0);
|
||||
pc_ldo:
|
||||
GenNative(m_cmp_abs, absolute, q, lab, 0);
|
||||
end; {case}
|
||||
GenLab(lab1);
|
||||
if rOpcode = pc_fjp then begin
|
||||
if op^.opcode = pc_grt then begin
|
||||
lab3 := GenLabel;
|
||||
GenNative(m_beq, relative, lab3, nil, 0);
|
||||
end; {if}
|
||||
GenNative(m_bcs, relative, lab2, nil, 0);
|
||||
if op^.opcode = pc_grt then
|
||||
GenLabUsedOnce(lab3);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab2);
|
||||
end {if}
|
||||
else if rOpcode = pc_tjp then begin
|
||||
if op^.opcode = pc_grt then
|
||||
GenNative(m_beq, relative, lab2, nil, 0);
|
||||
GenNative(m_bcc, relative, lab2, nil, 0);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab2);
|
||||
end {else if}
|
||||
else if op^.opcode = pc_geq then begin
|
||||
GenNative(m_lda_imm, immediate, 0, nil, 0);
|
||||
GenImplied(m_rol_a);
|
||||
end {else if}
|
||||
else {if op^.opcode = pc_grt then} begin
|
||||
GenNative(m_beq, relative, lab2, nil, 0);
|
||||
GenNative(m_bcc, relative, lab2, nil, 0);
|
||||
GenImplied(m_iny);
|
||||
GenLab(lab2);
|
||||
GenImplied(m_tya);
|
||||
end; {else}
|
||||
end {if}
|
||||
else begin
|
||||
GenImplied(m_tay);
|
||||
gLong.preference := onStack;
|
||||
GenTree(op^.right);
|
||||
gLong.preference := A_X;
|
||||
GenTree(op^.left);
|
||||
if gLong.where = onStack then begin
|
||||
GenImplied(m_ply);
|
||||
GenImplied(m_pla);
|
||||
end {if}
|
||||
else begin
|
||||
GenImplied(m_tay);
|
||||
GenImplied(m_txa);
|
||||
end; {else}
|
||||
GenNative(m_ldx_imm, immediate, 1, nil, 0);
|
||||
GenNative(m_cmp_s, direct, 3, nil, 0);
|
||||
GenNative(m_bne, relative, lab1, nil, 0);
|
||||
GenImplied(m_tya);
|
||||
GenNative(m_cmp_s, direct, 1, nil, 0);
|
||||
GenLab(lab1);
|
||||
if op^.opcode = pc_grt then begin
|
||||
lab3 := GenLabel;
|
||||
GenNative(m_beq, relative, lab3, nil, 0);
|
||||
end; {if}
|
||||
GenNative(m_bcs, relative, lab2, nil, 0);
|
||||
if op^.opcode = pc_grt then
|
||||
GenLab(lab3);
|
||||
GenImplied(m_dex);
|
||||
GenLab(lab2);
|
||||
GenImplied(m_pla);
|
||||
GenImplied(m_pla);
|
||||
GenImplied(m_txa);
|
||||
if rOpcode = pc_fjp then begin
|
||||
lab4 := GenLabel;
|
||||
GenNative(m_bne, relative, lab4, nil, 0);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab4);
|
||||
end {if}
|
||||
else if rOpcode = pc_tjp then begin
|
||||
lab4 := GenLabel;
|
||||
GenNative(m_beq, relative, lab4, nil, 0);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab4);
|
||||
end; {else if}
|
||||
end; {else}
|
||||
lab1 := GenLabel;
|
||||
GenNative(m_ldx_imm, immediate, 1, nil, 0);
|
||||
GenNative(m_cmp_s, direct, 3, nil, 0);
|
||||
GenNative(m_bne, relative, lab1, nil, 0);
|
||||
GenImplied(m_tya);
|
||||
GenNative(m_cmp_s, direct, 1, nil, 0);
|
||||
GenLab(lab1);
|
||||
lab2 := GenLabel;
|
||||
if op^.opcode = pc_grt then begin
|
||||
lab3 := GenLabel;
|
||||
GenNative(m_beq, relative, lab3, nil, 0);
|
||||
end; {if}
|
||||
GenNative(m_bcs, relative, lab2, nil, 0);
|
||||
if op^.opcode = pc_grt then
|
||||
GenLab(lab3);
|
||||
GenImplied(m_dex);
|
||||
GenLab(lab2);
|
||||
GenImplied(m_pla);
|
||||
GenImplied(m_pla);
|
||||
GenImplied(m_txa);
|
||||
if rOpcode = pc_fjp then begin
|
||||
lab4 := GenLabel;
|
||||
GenNative(m_bne, relative, lab4, nil, 0);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab4);
|
||||
end {if}
|
||||
else if rOpcode = pc_tjp then begin
|
||||
lab4 := GenLabel;
|
||||
GenNative(m_beq, relative, lab4, nil, 0);
|
||||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab4);
|
||||
end; {else if}
|
||||
end;
|
||||
|
||||
cgReal,cgDouble,cgComp,cgExtended: begin
|
||||
|
@ -2135,10 +2253,14 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
|||
num := op^.right^.q;
|
||||
lab1 := GenLabel;
|
||||
if opcode in [pc_fjp,pc_tjp] then begin
|
||||
if num <> 0 then
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0)
|
||||
else if NeedsCondition(leftOp) then
|
||||
GenImpliedForFlags(m_tay);
|
||||
if num = 0 then begin
|
||||
if NeedsCondition(leftOp) then
|
||||
GenImpliedForFlags(m_tay);
|
||||
end {if}
|
||||
else if num = 1 then
|
||||
GenImplied(m_dea)
|
||||
else
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
if opcode = pc_fjp then
|
||||
GenNative(beq, relative, lab1, nil, 0)
|
||||
else
|
||||
|
@ -2147,12 +2269,20 @@ if (op^.optype in [cgByte,cgUByte,cgWord,cgUWord]) and
|
|||
GenLab(lab1);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_ldx_imm, immediate, 0, nil, 0);
|
||||
GenNative(m_cmp_imm, immediate, num, nil, 0);
|
||||
GenNative(bne, relative, lab1, nil, 0);
|
||||
GenImplied(m_inx);
|
||||
GenLab(lab1);
|
||||
GenImplied(m_txa);
|
||||
if num <> 0 then
|
||||
GenNative(m_eor_imm, immediate, num, nil, 0)
|
||||
else if NeedsCondition(leftOp) then
|
||||
GenImpliedForFlags(m_tax);
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
if op^.opcode = pc_equ then begin
|
||||
GenNative(m_lda_imm, immediate, $ffff, nil, 0);
|
||||
GenLab(lab1);
|
||||
GenImplied(m_ina);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {else}
|
||||
end; {else}
|
||||
end {if}
|
||||
else if (op^.optype in [cgLong,cgULong]) and (leftOp in [pc_ldo,pc_lod])
|
||||
|
@ -2167,24 +2297,20 @@ else if (op^.optype in [cgLong,cgULong]) and (leftOp in [pc_ldo,pc_lod])
|
|||
GenNative(m_brl, longrelative, lb, nil, 0);
|
||||
GenLab(lab1);
|
||||
end {if}
|
||||
else if op^.opcode = pc_equ then begin
|
||||
lab1 := GenLabel;
|
||||
lab2 := GenLabel;
|
||||
DoOr(op^.left);
|
||||
GenNative(bne, relative, lab1, nil, 0);
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenNative(m_bra, relative, lab2, nil, 0);
|
||||
GenLab(lab1);
|
||||
GenNative(m_lda_imm, immediate, 0, nil, 0);
|
||||
GenLab(lab2);
|
||||
end {else if}
|
||||
else {if op^.opcode = pc_neq then} begin
|
||||
else begin
|
||||
lab1 := GenLabel;
|
||||
DoOr(op^.left);
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {else if}
|
||||
if op^.opcode = pc_equ then begin
|
||||
GenNative(m_lda_imm, immediate, $ffff, nil, 0);
|
||||
GenLab(lab1);
|
||||
GenImplied(m_ina);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {else}
|
||||
end; {else}
|
||||
end {else if}
|
||||
else if (op^.optype in [cgLong,cgULong]) and (rightOp in [pc_ldo,pc_lod]) then begin
|
||||
gLong.preference := A_X;
|
||||
|
@ -2229,8 +2355,7 @@ else
|
|||
if Complex(op^.right) or (not (opcode in [pc_fjp,pc_tjp])) then begin
|
||||
GenImplied(m_pha);
|
||||
GenTree(op^.right);
|
||||
GenImplied(m_sec);
|
||||
GenNative(m_sbc_s, direct, 1, nil, 0);
|
||||
GenNative(m_eor_s, direct, 1, nil, 0);
|
||||
GenImplied(m_plx);
|
||||
GenImplied(m_tax);
|
||||
if opcode in [pc_fjp,pc_tjp] then begin
|
||||
|
@ -2245,10 +2370,15 @@ else
|
|||
else begin
|
||||
lab1 := GenLabel;
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenLab(lab1);
|
||||
if op^.opcode = pc_equ then
|
||||
GenNative(m_eor_imm, immediate, 1, nil, 0);
|
||||
if op^.opcode = pc_equ then begin
|
||||
GenNative(m_lda_imm, immediate, $ffff, nil, 0);
|
||||
GenLab(lab1);
|
||||
GenImplied(m_ina);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {else}
|
||||
end; {else}
|
||||
end {if}
|
||||
else begin
|
||||
|
@ -2392,10 +2522,15 @@ else
|
|||
else begin
|
||||
lab3 := GenLabel;
|
||||
GenNative(m_beq, relative, lab3, nil, 0);
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenLab(lab3);
|
||||
if op^.opcode = pc_equ then
|
||||
GenNative(m_eor_imm, immediate, 1, nil, 0);
|
||||
if op^.opcode = pc_equ then begin
|
||||
GenNative(m_lda_imm, immediate, $ffff, nil, 0);
|
||||
GenLab(lab3);
|
||||
GenImplied(m_ina);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenLab(lab3);
|
||||
end; {else}
|
||||
end; {else}
|
||||
end; {case optype of cgQuad,cgUQuad}
|
||||
|
||||
|
@ -3148,81 +3283,44 @@ case optype of
|
|||
gQuad := lQuad;
|
||||
gQuad.where := gQuad.preference; {unless overridden later}
|
||||
if gLong.where = inPointer then begin
|
||||
if q = 0 then begin
|
||||
if gLong.fixedDisp then begin
|
||||
GenNative(m_ldy_imm, immediate, 6, nil, 0);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(6);
|
||||
GenImplied(m_dey);
|
||||
GenImplied(m_dey);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(4);
|
||||
GenImplied(m_dey);
|
||||
GenImplied(m_dey);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(2);
|
||||
GenNative(m_lda_indl, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(0);
|
||||
end {if}
|
||||
if gLong.fixedDisp then begin
|
||||
GenNative(m_ldy_imm, immediate, q+6, nil, 0);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(6);
|
||||
GenNative(m_ldy_imm, immediate, q+4, nil, 0);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(4);
|
||||
GenNative(m_ldy_imm, immediate, q+2, nil, 0);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(2);
|
||||
if q = 0 then
|
||||
GenNative(m_lda_indl, direct, gLong.disp, nil, 0)
|
||||
else begin
|
||||
GenImplied(m_tya);
|
||||
GenImplied(m_clc);
|
||||
GenNative(m_adc_imm, immediate, 6, nil, 0);
|
||||
GenImplied(m_tay);
|
||||
GenNative(m_ldy_imm, immediate, q, nil, 0);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(6);
|
||||
GenImplied(m_dey);
|
||||
GenImplied(m_dey);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(4);
|
||||
GenImplied(m_dey);
|
||||
GenImplied(m_dey);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(2);
|
||||
GenImplied(m_dey);
|
||||
GenImplied(m_dey);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(0);
|
||||
end; {else}
|
||||
end {if q = 0}
|
||||
StoreWordOfQuad(0);
|
||||
end {if}
|
||||
else begin
|
||||
if gLong.fixedDisp then begin
|
||||
GenNative(m_ldy_imm, immediate, q+6, nil, 0);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(6);
|
||||
GenImplied(m_dey);
|
||||
GenImplied(m_dey);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(4);
|
||||
GenImplied(m_dey);
|
||||
GenImplied(m_dey);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(2);
|
||||
GenImplied(m_dey);
|
||||
GenImplied(m_dey);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(0);
|
||||
end {if}
|
||||
else begin
|
||||
GenImplied(m_tya);
|
||||
GenImplied(m_clc);
|
||||
GenNative(m_adc_imm, immediate, q+6, nil, 0);
|
||||
GenImplied(m_tay);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(6);
|
||||
GenImplied(m_dey);
|
||||
GenImplied(m_dey);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(4);
|
||||
GenImplied(m_dey);
|
||||
GenImplied(m_dey);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(2);
|
||||
GenImplied(m_dey);
|
||||
GenImplied(m_dey);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
StoreWordOfQuad(0);
|
||||
end; {else}
|
||||
gQuad.where := onStack;
|
||||
GenImplied(m_tya);
|
||||
GenImplied(m_clc);
|
||||
GenNative(m_adc_imm, immediate, q+6, nil, 0);
|
||||
GenImplied(m_tay);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
GenImplied(m_pha);
|
||||
GenImplied(m_dey);
|
||||
GenImplied(m_dey);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
GenImplied(m_pha);
|
||||
GenImplied(m_dey);
|
||||
GenImplied(m_dey);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
GenImplied(m_pha);
|
||||
GenImplied(m_dey);
|
||||
GenImplied(m_dey);
|
||||
GenNative(m_lda_indly, direct, gLong.disp, nil, 0);
|
||||
GenImplied(m_pha);
|
||||
end; {else}
|
||||
end {if glong.where = inPointer}
|
||||
else if gLong.where = localAddress then begin
|
||||
|
@ -3617,11 +3715,17 @@ else begin
|
|||
else begin
|
||||
if op^.left^.opcode = pc_lao then begin
|
||||
GenTree(op^.right);
|
||||
if signed then
|
||||
GenImplied(m_tay);
|
||||
GenNative(m_ldx_imm, immediate, op^.left^.q, op^.left^.lab, shift16);
|
||||
if signed then begin
|
||||
GenImpliedForFlags(m_tay);
|
||||
lab2 := GenLabel;
|
||||
GenNative(m_bpl, relative, lab2, nil, 0);
|
||||
GenImplied(m_dex);
|
||||
GenLab(lab2);
|
||||
signed := false;
|
||||
end; {if}
|
||||
GenImplied(m_clc);
|
||||
GenNative(m_adc_imm, immediate, op^.left^.q, op^.left^.lab, 0);
|
||||
GenNative(m_ldx_imm, immediate, op^.left^.q, op^.left^.lab, shift16);
|
||||
end {if}
|
||||
else begin
|
||||
gLong.preference := onStack;
|
||||
|
@ -3696,7 +3800,7 @@ var
|
|||
GenNative(m_inc_dirx, direct, 2, nil, 0);
|
||||
GenLab(lab1);
|
||||
end {if}
|
||||
else {if op in [pc_gdl,pc_gld] then} begin
|
||||
else {if op in [pc_ldl,pc_lld] then} begin
|
||||
lab1 := GenLabel;
|
||||
if p = 1 then begin
|
||||
GenNative(m_lda_dirx, direct, 0, nil, 0);
|
||||
|
@ -5493,10 +5597,11 @@ procedure GenTree {op: icptr};
|
|||
lab1: integer;
|
||||
operandIsBoolean: boolean;
|
||||
|
||||
begin {GenntNgiNot}
|
||||
begin {GenBntNgiNot}
|
||||
if op^.opcode = pc_not then
|
||||
operandIsBoolean := op^.left^.opcode in
|
||||
[pc_and,pc_ior,pc_neq,pc_equ,pc_geq,pc_leq,pc_les,pc_grt,pc_not];
|
||||
[pc_and,pc_ior,pc_lnd,pc_lor,pc_not,pc_neq,pc_equ,pc_geq,pc_leq,
|
||||
pc_les,pc_grt];
|
||||
GenTree(op^.left);
|
||||
case op^.opcode of
|
||||
pc_bnt:
|
||||
|
@ -5507,16 +5612,17 @@ procedure GenTree {op: icptr};
|
|||
GenImplied(m_ina);
|
||||
end; {case pc_ngi}
|
||||
|
||||
pc_not: begin
|
||||
pc_not:
|
||||
if not operandIsBoolean then begin
|
||||
lab1 := GenLabel;
|
||||
GenImpliedForFlags(m_tax);
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenNative(m_lda_imm, immediate, $ffff, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {if}
|
||||
GenNative(m_eor_imm, immediate, 1, nil, 0);
|
||||
end; {if}
|
||||
GenImplied(m_ina);
|
||||
end {if}
|
||||
else
|
||||
GenNative(m_eor_imm, immediate, 1, nil, 0);
|
||||
end; {case}
|
||||
end; {GenBntNgiNot}
|
||||
|
||||
|
@ -6504,49 +6610,50 @@ procedure GenTree {op: icptr};
|
|||
{ Generate code for a pc_lor or pc_lnd }
|
||||
|
||||
var
|
||||
lab1,lab2: integer; {label}
|
||||
opc: pcodes; {operation code}
|
||||
|
||||
|
||||
procedure DoOra;
|
||||
|
||||
{ do some common oring operations to reduce space }
|
||||
|
||||
begin {DoOra}
|
||||
if gLong.where = onStack then begin
|
||||
GenImplied(m_pla);
|
||||
GenNative(m_sta_dir, direct, dworkLoc, nil, 0);
|
||||
GenImplied(m_pla);
|
||||
end {if}
|
||||
else
|
||||
GenNative(m_stx_dir, direct, dworkLoc, nil, 0);
|
||||
GenNative(m_ora_dir, direct, dworkLoc, nil, 0);
|
||||
end; {DoOra}
|
||||
|
||||
lab1,lab2,lab3,lab4: integer; {labels}
|
||||
|
||||
begin {GenLorLnd}
|
||||
opc := op^.opcode;
|
||||
lab1 := GenLabel;
|
||||
lab3 := GenLabel;
|
||||
lab4 := GenLabel;
|
||||
|
||||
gLong.preference := A_X;
|
||||
GenTree(op^.left);
|
||||
DoOra;
|
||||
|
||||
lab2 := GenLabel;
|
||||
if opc = pc_lnd then
|
||||
GenNative(m_bne, relative, lab2, nil, 0)
|
||||
if glong.where = A_X then
|
||||
GenImpliedForFlags(m_tay)
|
||||
else begin
|
||||
GenNative(m_beq, relative, lab2, nil, 0);
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenImplied(m_plx);
|
||||
GenImplied(m_pla);
|
||||
end; {else}
|
||||
GenNative(m_brl, longrelative, lab1, nil, 0);
|
||||
GenLab(lab2);
|
||||
GenNative(m_bne, relative, lab1, nil, 0);
|
||||
GenImplied(m_txa);
|
||||
if op^.opcode = pc_lor then begin
|
||||
lab2 := GenLabel;
|
||||
GenNative(m_beq, relative, lab2, nil, 0);
|
||||
GenLabUsedOnce(lab1);
|
||||
GenNative(m_brl, longrelative, lab3, nil, 0);
|
||||
GenLab(lab2);
|
||||
end {if}
|
||||
else begin
|
||||
GenNative(m_bne, relative, lab1, nil, 0);
|
||||
GenNative(m_brl, longrelative, lab4, nil, 0);
|
||||
GenLab(lab1);
|
||||
end; {if}
|
||||
|
||||
gLong.preference := A_X;
|
||||
GenTree(op^.right);
|
||||
DoOra;
|
||||
GenNative(m_beq, relative, lab1, nil, 0);
|
||||
if glong.where = A_X then
|
||||
GenImpliedForFlags(m_tay)
|
||||
else begin
|
||||
GenImplied(m_plx);
|
||||
GenImplied(m_pla);
|
||||
end; {else}
|
||||
GenNative(m_bne, relative, lab3, nil, 0);
|
||||
GenImplied(m_txa);
|
||||
GenNative(m_beq, relative, lab4, nil, 0);
|
||||
GenLab(lab3);
|
||||
GenNative(m_lda_imm, immediate, 1, nil, 0);
|
||||
GenLab(lab1);
|
||||
GenLab(lab4);
|
||||
end; {GenLorLnd}
|
||||
|
||||
|
||||
|
@ -7723,7 +7830,7 @@ var
|
|||
localSize := localSize + size;
|
||||
end {else if}
|
||||
else if opcode in
|
||||
[pc_les,pc_leq,pc_grt,pc_geq,pc_sto,pc_cpi,pc_ind,pc_lor,pc_lnd,
|
||||
[pc_les,pc_leq,pc_grt,pc_geq,pc_sto,pc_cpi,pc_ind,
|
||||
pc_ili,pc_iil,pc_idl,pc_ild,pc_ixa]
|
||||
then begin
|
||||
if dworkLoc = 0 then begin
|
||||
|
|
|
@ -18,7 +18,7 @@ uses CCommon, MM, Scanner, Symbol, CGI;
|
|||
{$segment 'HEADER'}
|
||||
|
||||
const
|
||||
symFileVersion = 40; {version number of .sym file format}
|
||||
symFileVersion = 44; {version number of .sym file format}
|
||||
|
||||
var
|
||||
inhibitHeader: boolean; {should .sym includes be blocked?}
|
||||
|
@ -722,6 +722,7 @@ procedure EndInclude {chPtr: ptr};
|
|||
WriteByte(ord(token.prefix));
|
||||
end;
|
||||
otherCharacter: WriteByte(ord(token.ch));
|
||||
preprocessingNumber:WriteWord(token.errCode);
|
||||
macroParameter: WriteWord(token.pnum);
|
||||
reservedSymbol: if token.kind in [lbracech,rbracech,lbrackch,
|
||||
rbrackch,poundch,poundpoundop] then
|
||||
|
@ -1392,6 +1393,7 @@ var
|
|||
token.prefix := charStrPrefixEnum(ReadByte);
|
||||
end;
|
||||
otherCharacter: token.ch := chr(ReadByte);
|
||||
preprocessingNumber: token.errCode := ReadWord;
|
||||
macroParameter: token.pnum := ReadWord;
|
||||
reservedSymbol: if token.kind in [lbracech,rbracech,lbrackch,
|
||||
rbrackch,poundch,poundpoundop] then
|
||||
|
|
Binary file not shown.
54
Native.pas
54
Native.pas
|
@ -110,6 +110,14 @@ procedure GenLab (lnum: integer);
|
|||
{ lnum - label number }
|
||||
|
||||
|
||||
procedure GenLabUsedOnce (lnum: integer);
|
||||
|
||||
{ generate a label that is only targeted by one branch }
|
||||
{ }
|
||||
{ parameters: }
|
||||
{ lnum - label number }
|
||||
|
||||
|
||||
procedure InitFile (keepName: gsosOutStringPtr; keepFlag: integer; partial: boolean);
|
||||
|
||||
{ Set up the object file }
|
||||
|
@ -1637,7 +1645,7 @@ var
|
|||
end; {if}
|
||||
|
||||
m_bcs,m_beq,m_bne,m_bmi,m_bpl,m_bcc:
|
||||
if npeep[ns+2].opcode = d_lab then
|
||||
if npeep[ns+2].opcode = d_lab then begin
|
||||
if npeep[ns+2].operand = operand then
|
||||
if npeep[ns+1].opcode = m_brl then begin
|
||||
if Short(ns,npeep[ns+1].operand) then begin
|
||||
|
@ -1674,8 +1682,20 @@ var
|
|||
opcode := m_bmi;
|
||||
end {else if m_bra}
|
||||
else if npeep[ns+3].opcode in [m_bra,m_brl] then
|
||||
if Short(ns,npeep[ns+3].operand) then
|
||||
if Short(ns,npeep[ns+3].operand) then begin
|
||||
operand := npeep[ns+3].operand;
|
||||
if (npeep[ns+2].flags & labelUsedOnce) <> 0 then
|
||||
Remove(ns+2);
|
||||
end; {if}
|
||||
end {if}
|
||||
else if npeep[ns+3].opcode = d_lab then
|
||||
if npeep[ns+3].operand = operand then
|
||||
if npeep[ns+4].opcode in [m_bra,m_brl] then
|
||||
if Short(ns,npeep[ns+4].operand) then begin
|
||||
operand := npeep[ns+4].operand;
|
||||
if (npeep[ns+3].flags & labelUsedOnce) <> 0 then
|
||||
Remove(ns+3);
|
||||
end; {if}
|
||||
|
||||
m_brl:
|
||||
if Short(ns,operand) then begin
|
||||
|
@ -1700,11 +1720,12 @@ var
|
|||
Remove(ns+3);
|
||||
end; {if}
|
||||
|
||||
m_dec_abs:
|
||||
{disabled - can generate bad code}
|
||||
{m_dec_abs:
|
||||
if npeep[ns+1].opcode = m_lda_abs then
|
||||
if name^ = npeep[ns+1].name^ then
|
||||
if npeep[ns+2].opcode = m_beq then
|
||||
Remove(ns+1);
|
||||
Remove(ns+1);}
|
||||
|
||||
m_lda_abs:
|
||||
if npeep[ns+1].opcode = m_clc then begin
|
||||
|
@ -2301,6 +2322,18 @@ GenNative(d_lab, gnrlabel, lnum, nil, 0);
|
|||
end; {GenLab}
|
||||
|
||||
|
||||
procedure GenLabUsedOnce {lnum: integer};
|
||||
|
||||
{ generate a label that is only targeted by one branch }
|
||||
{ }
|
||||
{ parameters: }
|
||||
{ lnum - label number }
|
||||
|
||||
begin {GenLabUsedOnce}
|
||||
GenNative(d_lab, gnrlabel, lnum, nil, labelUsedOnce);
|
||||
end; {GenLabUsedOnce}
|
||||
|
||||
|
||||
procedure InitFile {keepName: gsosOutStringPtr; keepFlag: integer; partial: boolean};
|
||||
|
||||
{ Set up the object file }
|
||||
|
@ -2546,6 +2579,17 @@ procedure InitFile {keepName: gsosOutStringPtr; keepFlag: integer; partial: bool
|
|||
{set the data bank register}
|
||||
SetDataBank;
|
||||
|
||||
{set FPE slot, if using FPE}
|
||||
if floatCard = 1 then begin
|
||||
CnOut(m_lda_imm);
|
||||
if floatSlot in [1..7] then
|
||||
CnOut2(floatSlot)
|
||||
else
|
||||
CnOut2(0);
|
||||
CnOut(m_jsl);
|
||||
RefName(@'~INITFLOAT', 0, 3, 0);
|
||||
end; {if}
|
||||
|
||||
{write JSL to main entry point}
|
||||
CnOut(m_jsl);
|
||||
if rtl then
|
||||
|
@ -2614,7 +2658,7 @@ yRegister.condition := regUnknown;
|
|||
lastRegOpcode := 0; {BRK}
|
||||
nnextspot := 1;
|
||||
nleadOpcodes := [m_asl_a,m_bcc,m_bcs,m_beq,m_bmi,m_bne,m_bpl,m_brl,{m_bvs,}
|
||||
m_dec_abs,m_lda_abs,m_lda_dir,m_lda_imm,m_ldx_imm,m_sta_abs,m_sta_dir,
|
||||
{m_dec_abs,}m_lda_abs,m_lda_dir,m_lda_imm,m_ldx_imm,m_sta_abs,m_sta_dir,
|
||||
m_pha,m_plb,{m_plx,}m_tax,m_tya,m_tyx,m_phy,m_pei_dir,m_ldy_imm,m_rep,
|
||||
m_ora_dir,m_ora_abs,m_and_imm,m_pea,m_tcd];
|
||||
nstopOpcodes := [d_end,d_pin];
|
||||
|
|
|
@ -35,6 +35,6 @@ int fcntl(int, int, ...);
|
|||
long lseek(int, long, int);
|
||||
int open(const char *, int, ...);
|
||||
int read(int, void *, unsigned);
|
||||
int write(int, void *, unsigned);
|
||||
int write(int, const void *, unsigned);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,13 +14,17 @@
|
|||
#ifndef __GSBUG__
|
||||
#define __GSBUG__
|
||||
|
||||
/* Error Codes */
|
||||
#define debugUnImpErr 0xFF01
|
||||
#define debugBadSelErr 0xFF02
|
||||
|
||||
#define dgiProgramCounter 0 /* for DebugGetInfo */
|
||||
|
||||
extern pascal Word DebugVersion() inline(0x04FF,dispatcher);
|
||||
extern pascal Word DebugStatus() inline(0x06FF,dispatcher);
|
||||
extern pascal void DebugStr() inline(0x09FF,dispatcher);
|
||||
extern pascal void SetMileStone() inline(0x0AFF,dispatcher);
|
||||
extern pascal void DebugSetHook() inline(0x0BFF,dispatcher);
|
||||
extern pascal LongWord DebugGetInfo() inline(0x0CFF,dispatcher);
|
||||
extern pascal Word DebugVersion(void) inline(0x04FF,dispatcher);
|
||||
extern pascal Word DebugStatus(void) inline(0x06FF,dispatcher);
|
||||
extern pascal void DebugStr(Pointer) inline(0x09FF,dispatcher);
|
||||
extern pascal void SetMileStone(Pointer) inline(0x0AFF,dispatcher);
|
||||
extern pascal void DebugSetHook(VoidProcPtr) inline(0x0BFF,dispatcher);
|
||||
extern pascal LongWord DebugGetInfo(Word) inline(0x0CFF,dispatcher);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
#define invalidFSTop 0x0065 /* invalid FST operation */
|
||||
#define fstCaution 0x0066 /* FST handled call, but result is weird */
|
||||
#define devNameErr 0x0067 /* device exists with same name as replacement name */
|
||||
#define defListFull 0x0068 /* device list is full */
|
||||
#define devListFull 0x0068 /* device list is full */
|
||||
#define supListFull 0x0069 /* supervisor list is full */
|
||||
#define fstError 0x006a /* generic FST error */
|
||||
#define resExistsErr 0x0070 /* cannot expand file, resource already exists */
|
||||
|
|
|
@ -150,6 +150,9 @@ int ilogbl(long double);
|
|||
double ldexp(double, int);
|
||||
float ldexpf(float, int);
|
||||
long double ldexpl(long double, int);
|
||||
double lgamma(double);
|
||||
float lgammaf(float);
|
||||
long double lgammal(long double);
|
||||
#if defined(__ORCAC_HAS_LONG_LONG__) || __STDC_VERSION__ >= 199901L
|
||||
long long llrint(double);
|
||||
long long llrintf(float);
|
||||
|
|
|
@ -23,7 +23,7 @@ typedef unsigned long size_t;
|
|||
#endif
|
||||
|
||||
#ifndef __KeepNamespacePure__
|
||||
char *c2pstr(char *);
|
||||
char *c2pstr(const char *);
|
||||
#endif
|
||||
void *memchr(const void *, int, size_t);
|
||||
int memcmp(const void *, const void *, size_t);
|
||||
|
@ -31,7 +31,7 @@ void *memcpy(void *, const void *, size_t);
|
|||
void *memmove(void *, const void *, size_t);
|
||||
void *memset(void *, int, size_t);
|
||||
#ifndef __KeepNamespacePure__
|
||||
char *p2cstr(char *);
|
||||
char *p2cstr(const char *);
|
||||
#endif
|
||||
char *strcat(char *, const char *);
|
||||
char *strchr(const char *, int);
|
||||
|
@ -46,12 +46,12 @@ int strncmp(const char *, const char *, size_t);
|
|||
char *strncpy(char *, const char *, size_t);
|
||||
char *strpbrk(const char *, const char *);
|
||||
#ifndef __KeepNamespacePure__
|
||||
int strpos(char *, char);
|
||||
int strpos(const char *, char);
|
||||
#endif
|
||||
char *strrchr(const char *, int);
|
||||
#ifndef __KeepNamespacePure__
|
||||
char *strrpbrk(char *, char *);
|
||||
int strrpos(char *, char);
|
||||
char *strrpbrk(const char *, const char *);
|
||||
int strrpos(const char *, char);
|
||||
#endif
|
||||
size_t strspn(const char *, const char *);
|
||||
char *strstr(const char *, const char *);
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
#define hypot(x,y) __tg_real_x_y(hypot,(x),(y))
|
||||
#define ilogb(x) __tg_real_x(ilogb,(x))
|
||||
#define ldexp(x,n) __tg_real_x_other(ldexp,(x),(n))
|
||||
#define lgamma(x) __tg_real_x(lgamma,(x))
|
||||
#define llrint(x) __tg_real_x(llrint,(x))
|
||||
#define llround(x) __tg_real_x(llround,(x))
|
||||
#define log(x) __tg_x(log,(x))
|
||||
|
|
68
Parser.pas
68
Parser.pas
|
@ -122,13 +122,6 @@ type
|
|||
val: longlong; {switch value}
|
||||
end;
|
||||
|
||||
{token stack}
|
||||
{-----------}
|
||||
tokenStackPtr = ^tokenStackRecord;
|
||||
tokenStackRecord = record
|
||||
next: tokenStackPtr;
|
||||
token: tokenType;
|
||||
end;
|
||||
{statement stack}
|
||||
{---------------}
|
||||
statementPtr = ^statementRecord;
|
||||
|
@ -157,7 +150,7 @@ type
|
|||
);
|
||||
forSt: (
|
||||
forLoop: integer; {branch here to loop}
|
||||
e3List: tokenStackPtr; {tokens for last expression}
|
||||
e3Code: codeRef; {code for last expression}
|
||||
);
|
||||
switchSt: (
|
||||
maxVal: longint; {max switch value}
|
||||
|
@ -690,11 +683,9 @@ var
|
|||
{ handle a for statement }
|
||||
|
||||
var
|
||||
errorFound: boolean; {did we find an error?}
|
||||
e3Start: codeRef; {ref to start of code for expression 3}
|
||||
forLoop, continueLab, breakLab: integer; {branch points}
|
||||
parencount: integer; {number of unmatched '(' chars}
|
||||
stPtr: statementPtr; {work pointer}
|
||||
tl,tk: tokenStackPtr; {for forming expression list}
|
||||
|
||||
begin {ForStatement}
|
||||
NextToken; {skip the 'for' token}
|
||||
|
@ -733,29 +724,12 @@ var
|
|||
end; {if}
|
||||
Match(semicolonch,22);
|
||||
|
||||
tl := nil; {collect the tokens for the last expression}
|
||||
parencount := 0;
|
||||
errorFound := false;
|
||||
while (token.kind <> eofsy)
|
||||
and ((token.kind <> rparench) or (parencount <> 0))
|
||||
and (token.kind <> semicolonch) do begin
|
||||
new(tk); {place the token in the list}
|
||||
tk^.next := tl;
|
||||
tl := tk;
|
||||
tk^.token := token;
|
||||
if token.kind = lparench then {allow parens in the expression}
|
||||
parencount := parencount+1
|
||||
else if token.kind = rparench then
|
||||
parencount := parencount-1;
|
||||
NextToken; {next token}
|
||||
end; {while}
|
||||
if errorFound then {if an error was found, dump the list}
|
||||
while tl <> nil do begin
|
||||
tk := tl;
|
||||
tl := tl^.next;
|
||||
dispose(tk);
|
||||
end; {while}
|
||||
stPtr^.e3List := tl; {save the list}
|
||||
e3Start := GetCodeLocation; {generate and save code for expression 3}
|
||||
if token.kind <> rparench then begin
|
||||
Expression(normalExpression, [rparench]);
|
||||
Gen0t(pc_pop, UsualUnaryConversions);
|
||||
end; {if}
|
||||
stPtr^.e3Code := RemoveCode(e3Start);
|
||||
Match(rparench,12); {get the closing for loop paren}
|
||||
|
||||
if c99Scope then PushTable;
|
||||
|
@ -1128,37 +1102,13 @@ procedure EndForStatement;
|
|||
{ finish off a for statement }
|
||||
|
||||
var
|
||||
ltoken: tokenType; {for putting ; on stack}
|
||||
stPtr: statementPtr; {work pointer}
|
||||
tl,tk: tokenStackPtr; {for forming expression list}
|
||||
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
|
||||
|
||||
begin {EndForStatement}
|
||||
if c99Scope then PopTable;
|
||||
stPtr := statementList;
|
||||
Gen1(dc_lab, stPtr^.continueLab); {define the continue label}
|
||||
|
||||
tl := stPtr^.e3List; {place the expression back in the list}
|
||||
if tl <> nil then begin
|
||||
PutBackToken(token, false, false);
|
||||
ltoken.kind := semicolonch;
|
||||
ltoken.class := reservedSymbol;
|
||||
PutBackToken(ltoken, false, false);
|
||||
while tl <> nil do begin
|
||||
PutBackToken(tl^.token, false, false);
|
||||
tk := tl;
|
||||
tl := tl^.next;
|
||||
dispose(tk);
|
||||
end; {while}
|
||||
lSuppressMacroExpansions := suppressMacroExpansions; {inhibit token echo}
|
||||
suppressMacroExpansions := true;
|
||||
NextToken; {evaluate the expression}
|
||||
Expression(normalExpression, [semicolonch]);
|
||||
Gen0t(pc_pop, UsualUnaryConversions);
|
||||
NextToken; {skip the semicolon}
|
||||
suppressMacroExpansions := lSuppressMacroExpansions;
|
||||
end; {if}
|
||||
|
||||
InsertCode(stPtr^.e3Code); {insert code for expression 3}
|
||||
Gen1(pc_ujp, stPtr^.forLoop); {loop to the test}
|
||||
Gen1(dc_lab, stPtr^.breakLab); {create the exit label}
|
||||
statementList := stPtr^.next; {pop the statement record}
|
||||
|
|
|
@ -52,7 +52,7 @@ const
|
|||
feature_ll = true;
|
||||
feature_s_long = false;
|
||||
feature_n_size = true;
|
||||
feature_scanf_ld = false;
|
||||
feature_scanf_ld = true;
|
||||
|
||||
type
|
||||
length_modifier = (default, h, hh, l, ll, j, z, t, ld);
|
||||
|
|
|
@ -49,4 +49,4 @@ Alternatively, you can keep the LF line endings in your working copy of the Git
|
|||
|
||||
[udl]: http://ftp.gno.org/pub/apple2/gs.specific/gno/file.convert/udl.114.shk
|
||||
|
||||
In addition to converting the line endings, you will also have to set the files to the appropriate file types before building ORCA/C on a IIGS. The included `settypes` script (for use under the ORCA shell) does this for the sources to the ORCA/C compiler itself, although it does not currently cover the test cases and headers.
|
||||
In addition to converting the line endings, you will also have to set the files to the appropriate file types before building ORCA/C on a IIGS. The included `settypes` script (for use under the ORCA shell) can be used to do this.
|
||||
|
|
201
Scanner.pas
201
Scanner.pas
|
@ -741,7 +741,7 @@ if list or (numErr <> 0) then begin
|
|||
122: msg := @'arithmetic is not allowed on a pointer to an incomplete or function type';
|
||||
123: msg := @'array element type may not be an incomplete or function type';
|
||||
124: msg := @'lint: invalid format string or arguments';
|
||||
125: msg := @'lint: format string is not a string literal';
|
||||
{125: msg := @'lint: format string is not a string literal';}
|
||||
126: msg := @'scope rules may not be changed within a function';
|
||||
127: msg := @'illegal storage class for declaration in for loop';
|
||||
128: msg := @'lint: integer overflow in expression';
|
||||
|
@ -756,7 +756,7 @@ if list or (numErr <> 0) then begin
|
|||
137: msg := @'atomic types are not supported by ORCA/C';
|
||||
138: msg := @'unsupported alignment';
|
||||
{139: msg := @'thread-local storage is not supported by ORCA/C';}
|
||||
140: msg := @'unexpected token';
|
||||
{140: msg := @'unexpected token';}
|
||||
141: msg := @'_Noreturn specifier is only allowed on functions';
|
||||
142: msg := @'_Alignas may not be used in this declaration or type name';
|
||||
143: msg := @'only object pointer types may be restrict-qualified';
|
||||
|
@ -805,6 +805,7 @@ if list or (numErr <> 0) then begin
|
|||
186: msg := @'lint: implicit conversion changes value of constant';
|
||||
187: msg := @'expression has incomplete struct or union type';
|
||||
188: msg := @'local variable used in asm statement is out of range for addressing mode';
|
||||
189: msg := @'malformed numeric constant';
|
||||
end; {case}
|
||||
if extraStr <> nil then begin
|
||||
extraStr^ := concat(msg^,extraStr^);
|
||||
|
@ -1097,6 +1098,8 @@ case token.kind of
|
|||
dotdotdotsy: write('...');
|
||||
|
||||
otherch: write(token.ch);
|
||||
|
||||
ppNumber: write(token.numString^);
|
||||
|
||||
macroParm: write('$', token.pnum:1);
|
||||
|
||||
|
@ -1118,16 +1121,11 @@ procedure CheckIdentifier; forward;
|
|||
{ See if an identifier is a reserved word, macro or typedef }
|
||||
|
||||
|
||||
procedure DoNumber (scanWork: boolean); forward;
|
||||
procedure DoNumber; forward;
|
||||
|
||||
{ The current character starts a number - scan it }
|
||||
{ }
|
||||
{ Parameters: }
|
||||
{ scanWork - get characters from workString? }
|
||||
{ Scan a number from workString }
|
||||
{ }
|
||||
{ Globals: }
|
||||
{ ch - first character in sequence; set to first char }
|
||||
{ after sequence }
|
||||
{ workString - string to take numbers from }
|
||||
|
||||
|
||||
|
@ -1311,6 +1309,7 @@ var
|
|||
class1,class2: tokenClass; {token classes}
|
||||
i: integer; {loop variable}
|
||||
kind1,kind2: tokenEnum; {token kinds}
|
||||
lsaveNumber: boolean; {local copy of saveNumber}
|
||||
lt: tokenType; {local copy of token}
|
||||
str1,str2: stringPtr; {identifier strings}
|
||||
|
||||
|
@ -1373,27 +1372,37 @@ else if class1 in numericConstants then begin
|
|||
str2 := @reservedWords[kind2]
|
||||
else if kind2 = dotch then
|
||||
str2 := @'.'
|
||||
else if (kind2 = plusch)
|
||||
and (tk1.numString^[length(tk1.numString^)] in ['e','E','p','P']) then
|
||||
str2 := @'+'
|
||||
else if (kind2 = minusch)
|
||||
and (tk1.numString^[length(tk1.numString^)] in ['e','E','p','P']) then
|
||||
str2 := @'-'
|
||||
else begin
|
||||
Error(63);
|
||||
goto 1;
|
||||
end; {else}
|
||||
workString := concat(tk1.numString^, str2^);
|
||||
lt := token;
|
||||
DoNumber(true);
|
||||
lsaveNumber := saveNumber;
|
||||
saveNumber := true;
|
||||
DoNumber;
|
||||
saveNumber := lsaveNumber;
|
||||
tk1 := token;
|
||||
token := lt;
|
||||
goto 1;
|
||||
end {else if class1 in numericConstants}
|
||||
|
||||
else if kind1 = dotch then begin
|
||||
if class2 in numericConstants then begin
|
||||
workString := concat(tk1.numString^, tk2.numString^);
|
||||
lt := token;
|
||||
DoNumber(true);
|
||||
tk1 := token;
|
||||
token := lt;
|
||||
goto 1;
|
||||
end; {if}
|
||||
if class2 in numericConstants then
|
||||
if charKinds[ord(tk2.numString^[1])] = digit then begin
|
||||
workString := concat('.', tk2.numString^);
|
||||
lt := token;
|
||||
DoNumber;
|
||||
tk1 := token;
|
||||
token := lt;
|
||||
goto 1;
|
||||
end; {if}
|
||||
end {else if class1 in numericConstants}
|
||||
|
||||
else if kind1 = poundch then begin
|
||||
|
@ -1878,6 +1887,8 @@ procedure Expand (macro: macroRecordPtr);
|
|||
{ Globals: }
|
||||
{ macroList - scanner putback buffer }
|
||||
|
||||
label 1;
|
||||
|
||||
type
|
||||
parameterPtr = ^parameterRecord;
|
||||
parameterRecord = record {parameter list element}
|
||||
|
@ -2156,8 +2167,10 @@ else begin
|
|||
tcPtr := pptr^.tokens;
|
||||
if tcPtr = nil then begin
|
||||
if tlPtr^.next <> nil then
|
||||
if tlPtr^.next^.token.kind = poundpoundop then
|
||||
tlPtr^.next := tlPtr^.next^.next;
|
||||
if tlPtr^.next^.token.kind = poundpoundop then begin
|
||||
tlPtr := tlPtr^.next;
|
||||
goto 1;
|
||||
end; {if}
|
||||
if lastPtr <> nil then
|
||||
if lastPtr^.token.kind = poundpoundop then
|
||||
if tokenList <> nil then
|
||||
|
@ -2179,7 +2192,7 @@ else begin
|
|||
if not tcPtr^.expandEnabled then
|
||||
inhibit := true;
|
||||
if tcPtr = pptr^.tokens then
|
||||
if (mPtr <> nil) and (mPtr^.parameters > 0) then
|
||||
if (mPtr <> nil) and (mPtr^.parameters >= 0) then
|
||||
inhibit := true;
|
||||
if (mPtr <> nil) and (not inhibit) then
|
||||
Expand(mPtr)
|
||||
|
@ -2209,7 +2222,7 @@ else begin
|
|||
tokenEnd := tlPtr^.tokenEnd;
|
||||
PutBackToken(tlPtr^.token, expandEnabled, false);
|
||||
end; {else}
|
||||
lastPtr := tlPtr;
|
||||
1: lastPtr := tlPtr;
|
||||
tlPtr := tlPtr^.next;
|
||||
end; {while}
|
||||
end; {else}
|
||||
|
@ -2786,8 +2799,12 @@ var
|
|||
ple: stringListPtr; {pointer to the last element in parameterList}
|
||||
pnum: integer; {for counting parameters}
|
||||
tPtr,tk1,tk2: tokenListRecordPtr; {pointer to a token}
|
||||
luseGlobalPool: boolean; {local copy of useGlobalPool}
|
||||
|
||||
begin {DoDefine}
|
||||
|
||||
lUseGlobalPool := useGlobalPool;
|
||||
useGlobalPool := true; {use global memory for defines}
|
||||
expandMacros := false; {block expansions}
|
||||
saveNumber := true; {save characters in numeric tokens}
|
||||
parameterList := nil; {no parameters yet}
|
||||
|
@ -2969,6 +2986,9 @@ var
|
|||
tk2^.token.sval^.str[i] then
|
||||
goto 3;
|
||||
end;
|
||||
preprocessingNumber:
|
||||
if tk1^.token.numString^ <> tk2^.token.numString^ then
|
||||
goto 3;
|
||||
macroParameter:
|
||||
if tk1^.token.pnum <> tk2^.token.pnum then
|
||||
goto 3;
|
||||
|
@ -2999,6 +3019,7 @@ var
|
|||
dispose(np);
|
||||
end; {while}
|
||||
saveNumber := false; {stop saving numeric strings}
|
||||
useGlobalPool := lUseGlobalPool;
|
||||
end; {DoDefine}
|
||||
|
||||
|
||||
|
@ -3148,9 +3169,11 @@ var
|
|||
else
|
||||
Error(18);
|
||||
if token.kind in [intconst,uintconst,ushortconst] then begin
|
||||
floatSlot := $C080 | (token.ival << 4);
|
||||
floatSlot := token.ival;
|
||||
NextToken;
|
||||
end {if}
|
||||
else if token.kind = eolsy then
|
||||
floatSlot := 0
|
||||
else
|
||||
Error(18);
|
||||
end; {DoFloat}
|
||||
|
@ -3493,7 +3516,9 @@ if ch in ['a','d','e','i','l','p','u','w'] then begin
|
|||
expandMacros := false;
|
||||
NextToken;
|
||||
expandMacros := true;
|
||||
if token.class <> identifier then begin
|
||||
if token.kind = floatsy then
|
||||
token.name := @'float'
|
||||
else if token.class <> identifier then begin
|
||||
if (lint & lintPragmas) <> 0 then
|
||||
Error(110);
|
||||
goto 2;
|
||||
|
@ -3849,22 +3874,19 @@ Error(err);
|
|||
end; {Error2}
|
||||
|
||||
|
||||
procedure DoNumber {scanWork: boolean};
|
||||
procedure DoNumber;
|
||||
|
||||
{ The current character starts a number - scan it }
|
||||
{ }
|
||||
{ Parameters: }
|
||||
{ scanWork - get characters from workString? }
|
||||
{ Scan a number from workString }
|
||||
{ }
|
||||
{ Globals: }
|
||||
{ ch - first character in sequence; set to first char }
|
||||
{ after sequence }
|
||||
{ workString - string to take numbers from }
|
||||
|
||||
label 1,2;
|
||||
|
||||
var
|
||||
atEnd: boolean; {at end of workString?}
|
||||
c2: char; {next character to process}
|
||||
err: integer; {error code}
|
||||
i: integer; {loop index}
|
||||
isBin: boolean; {is the value a binary number?}
|
||||
isHex: boolean; {is the value a hex number?}
|
||||
|
@ -3887,17 +3909,13 @@ var
|
|||
{ Return the next character that is a part of the number }
|
||||
|
||||
begin {NextChar}
|
||||
if scanWork then begin
|
||||
if ord(workString[0]) <> numIndex then begin
|
||||
numIndex := numIndex+1;
|
||||
c2 := workString[numIndex];
|
||||
end {if}
|
||||
else
|
||||
c2 := ' ';
|
||||
if ord(workString[0]) <> numIndex then begin
|
||||
numIndex := numIndex+1;
|
||||
c2 := workString[numIndex];
|
||||
end {if}
|
||||
else begin
|
||||
NextCh;
|
||||
c2 := ch;
|
||||
atEnd := true;
|
||||
c2 := ' ';
|
||||
end; {else}
|
||||
end; {NextChar}
|
||||
|
||||
|
@ -3909,8 +3927,10 @@ var
|
|||
{ code never actually get converted to numeric constants. }
|
||||
|
||||
begin {FlagError}
|
||||
if not skipping then
|
||||
Error(errCode);
|
||||
if err = 0 then
|
||||
err := errCode
|
||||
else if err <> errCode then
|
||||
err := 189;
|
||||
end; {FlagError}
|
||||
|
||||
|
||||
|
@ -3957,6 +3977,7 @@ var
|
|||
|
||||
|
||||
begin {DoNumber}
|
||||
atEnd := false; {not at end}
|
||||
isBin := false; {assume it's not binary}
|
||||
isHex := false; {assume it's not hex}
|
||||
isReal := false; {assume it's an integer}
|
||||
|
@ -3964,13 +3985,10 @@ isLong := false; {assume a short integer}
|
|||
isLongLong := false;
|
||||
isFloat := false;
|
||||
unsigned := false; {assume signed numbers}
|
||||
err := 0; {no error so far}
|
||||
stringIndex := 0; {no digits so far...}
|
||||
if scanWork then begin {set up the scanner}
|
||||
numIndex := 0;
|
||||
NextChar;
|
||||
end {if}
|
||||
else
|
||||
c2 := ch;
|
||||
numIndex := 0; {set up the scanner}
|
||||
NextChar;
|
||||
if c2 = '.' then begin {handle the case of no leading digits}
|
||||
stringIndex := 1;
|
||||
numString[1] := '0';
|
||||
|
@ -4039,6 +4057,8 @@ while c2 in ['l','u','L','U'] do {check for long or unsigned}
|
|||
if c2 = c1 then begin
|
||||
NextChar;
|
||||
isLongLong := true;
|
||||
if isReal then
|
||||
FlagError(156);
|
||||
end {if}
|
||||
else
|
||||
isLong := true;
|
||||
|
@ -4052,10 +4072,6 @@ while c2 in ['l','u','L','U'] do {check for long or unsigned}
|
|||
unsigned := true;
|
||||
end; {else}
|
||||
if c2 in ['f','F'] then begin {allow F designator on reals}
|
||||
if unsigned then
|
||||
FlagError(91);
|
||||
if isLongLong then
|
||||
FlagError(156);
|
||||
if not isReal then begin
|
||||
FlagError(100);
|
||||
isReal := true;
|
||||
|
@ -4134,6 +4150,8 @@ else begin {hex, octal, & binary}
|
|||
token.qval.hi := 0;
|
||||
if isHex then begin
|
||||
i := 3;
|
||||
if length(numString) < 3 then
|
||||
FlagError(189);
|
||||
while i <= length(numString) do begin
|
||||
if token.qval.hi & $F0000000 <> 0 then begin
|
||||
i := maxint;
|
||||
|
@ -4152,6 +4170,8 @@ else begin {hex, octal, & binary}
|
|||
end {if}
|
||||
else if isBin then begin
|
||||
i := 3;
|
||||
if length(numString) < 3 then
|
||||
FlagError(189);
|
||||
while i <= length(numString) do begin
|
||||
if token.qval.hi & $80000000 <> 0 then begin
|
||||
i := maxint;
|
||||
|
@ -4167,7 +4187,7 @@ else begin {hex, octal, & binary}
|
|||
end; {while}
|
||||
end {if}
|
||||
else begin
|
||||
i := 1;
|
||||
i := 2;
|
||||
while i <= length(numString) do begin
|
||||
if token.qval.hi & $E0000000 <> 0 then begin
|
||||
i := maxint;
|
||||
|
@ -4212,14 +4232,18 @@ else begin {hex, octal, & binary}
|
|||
token.class := intConstant;
|
||||
end; {else}
|
||||
end; {else}
|
||||
if saveNumber then begin
|
||||
sp := pointer(GMalloc(length(numString)+1));
|
||||
CopyString(pointer(sp), @numString);
|
||||
if not atEnd then {make sure we read all characters}
|
||||
FlagError(189);
|
||||
if err <> 0 then begin {handle unconvertible pp-numbers}
|
||||
token.class := preprocessingNumber;
|
||||
token.kind := ppnumber;
|
||||
token.errCode := err;
|
||||
end; {if}
|
||||
if saveNumber or (err <> 0) then begin
|
||||
sp := pointer(GMalloc(length(workString)+1));
|
||||
CopyString(pointer(sp), @workString);
|
||||
token.numString := sp;
|
||||
end; {if}
|
||||
if scanWork then {make sure we read all characters}
|
||||
if ord(workString[0]) <> numIndex then
|
||||
Error(63);
|
||||
end; {DoNumber}
|
||||
|
||||
|
||||
|
@ -4556,7 +4580,8 @@ lintErrors :=
|
|||
spaceStr := ' '; {strings used in stringization}
|
||||
quoteStr := '"';
|
||||
{set of classes for numeric constants}
|
||||
numericConstants := [intConstant,longConstant,longlongConstant,realConstant];
|
||||
numericConstants :=
|
||||
[intConstant,longConstant,longlongConstant,realConstant,preprocessingNumber];
|
||||
|
||||
new(mp); {__LINE__}
|
||||
mp^.name := @'__LINE__';
|
||||
|
@ -4787,7 +4812,7 @@ repeat
|
|||
else if lch in ['.','0'..'9'] then begin
|
||||
token.name := GetWord;
|
||||
saveNumber := true;
|
||||
DoNumber(true);
|
||||
DoNumber;
|
||||
saveNumber := false;
|
||||
end {else if}
|
||||
else if lch = '"' then
|
||||
|
@ -5311,6 +5336,44 @@ var
|
|||
end; {ConcatenateTokenString}
|
||||
|
||||
|
||||
procedure Number;
|
||||
|
||||
{ Scan a preprocessing number token. It is converted to an }
|
||||
{ integer or floating constant if it matches the syntax for }
|
||||
{ one of those, or left as a preprocessing number if not. }
|
||||
|
||||
var
|
||||
numLen: 1..maxint;
|
||||
lastCh: char;
|
||||
|
||||
begin {Number}
|
||||
numLen := 0;
|
||||
lastCh := chr(0);
|
||||
|
||||
while (charKinds[ord(ch)] in [digit,letter,ch_dot])
|
||||
or ((lastCh in ['e','E','p','P'])
|
||||
and (charKinds[ord(ch)] in [ch_plus,ch_dash])) do
|
||||
begin
|
||||
if numLen < 255 then begin
|
||||
numLen := numLen + 1;
|
||||
workString[numLen] := ch;
|
||||
end {if}
|
||||
else
|
||||
numLen := 256;
|
||||
lastCh := ch;
|
||||
NextCh;
|
||||
end; {while}
|
||||
if numLen = 256 then begin
|
||||
if not skipping then
|
||||
Error(131);
|
||||
numLen := 1;
|
||||
workString[1] := '0';
|
||||
end; {if}
|
||||
workString[0] := chr(numLen);
|
||||
DoNumber;
|
||||
end; {Number}
|
||||
|
||||
|
||||
begin {NextToken}
|
||||
if ifList = nil then {do pending EndInclude calls}
|
||||
while includeCount <> 0 do begin
|
||||
|
@ -5644,7 +5707,7 @@ case charKinds[ord(ch)] of
|
|||
|
||||
ch_dot : begin {tokens that start with '.'}
|
||||
if charKinds[ord(PeekCh)] = digit then
|
||||
DoNumber(false)
|
||||
Number
|
||||
else begin
|
||||
NextCh;
|
||||
if (ch = '.') and (PeekCh = '.') then begin
|
||||
|
@ -5857,7 +5920,7 @@ case charKinds[ord(ch)] of
|
|||
end;
|
||||
|
||||
digit : {numeric constants}
|
||||
DoNumber(false);
|
||||
Number;
|
||||
|
||||
ch_other: begin {other non-whitespace char (pp-token)}
|
||||
token.kind := otherch;
|
||||
|
@ -5915,10 +5978,20 @@ if printMacroExpansions then
|
|||
if not suppressMacroExpansions then
|
||||
if not suppressPrint then
|
||||
PrintToken(token); {print the token stream}
|
||||
if token.kind = otherch then
|
||||
if token.kind = otherch then begin
|
||||
if not (skipping or preprocessing or suppressMacroExpansions)
|
||||
or doingPPExpression then
|
||||
Error(1);
|
||||
end {if}
|
||||
else if token.kind = ppNumber then
|
||||
if not (skipping or preprocessing or suppressMacroExpansions)
|
||||
or doingPPExpression then begin
|
||||
Error(token.errCode);
|
||||
token.kind := intconst;
|
||||
token.class := intConstant;
|
||||
token.ival := 0;
|
||||
token.numString := @'0';
|
||||
end; {if}
|
||||
end; {NextToken}
|
||||
|
||||
|
||||
|
|
|
@ -309,6 +309,8 @@ charSym start single character symbols
|
|||
enum (barbarop,pluseqop,minuseqop,asteriskeqop,slasheqop)
|
||||
enum (percenteqop,ltlteqop,gtgteqop,andeqop,caroteqop)
|
||||
enum (bareqop,poundpoundop,dotdotdotsy)
|
||||
enum (ppnumber) preprocessing number
|
||||
enum (otherch) other non-whitespace char
|
||||
enum (eolsy,eofsy) control characters
|
||||
enum (typedef) user types
|
||||
! converted operations
|
||||
|
@ -466,6 +468,7 @@ icp start in-coming priority for expression
|
|||
dc i1'3' bareqop
|
||||
dc i1'200' poundpoundop
|
||||
dc i1'200' dotdotdotsy
|
||||
dc i1'200' ppnumber
|
||||
dc i1'200' otherch
|
||||
dc i1'200' eolsy
|
||||
dc i1'200' eofsy
|
||||
|
@ -644,6 +647,7 @@ isp start in stack priority for expression
|
|||
dc i1'2' bareqop
|
||||
dc i1'0' poundpoundop
|
||||
dc i1'0' dotdotdotsy
|
||||
dc i1'0' ppnumber
|
||||
dc i1'0' otherch
|
||||
dc i1'0' eolsy
|
||||
dc i1'0' eofsy
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
As with all Byte Works programs, if you have questions or are
|
||||
experiencing problems, we want to hear from you. You can contact us
|
||||
through the channels below.
|
||||
|
||||
E-mail: support@byteworks.us
|
||||
|
||||
Web Site: https://www.byteworks.us
|
||||
|
||||
ORCA/C is now maintained on GitHub by community members. Bug reports
|
||||
or support requests can be submitted on its issues page:
|
||||
|
||||
https://github.com/byteworksinc/ORCA-C/issues
|
|
@ -34,7 +34,7 @@ second string argument!"))
|
|||
goto Fail;
|
||||
|
||||
strcpy(s1, "this is the first string argument");
|
||||
strcpy(s1, strncat (s1, s2, -5));
|
||||
strcpy(s1, strncat (s1, s2, 0));
|
||||
if (strcmp (s1, "this is the first string argument"))
|
||||
goto Fail;
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ int main (void)
|
|||
if (i != 0)
|
||||
goto Fail;
|
||||
|
||||
i = strncmp (s1, s2, -90L); /* should just return 0 */
|
||||
i = strncmp (s1, s2, 0L); /* should just return 0 */
|
||||
if (i != 0)
|
||||
goto Fail;
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ int main (void)
|
|||
if (i != 1)
|
||||
goto Fail3;
|
||||
string [41] = '\0';
|
||||
if (strcmp (string, " +009. -0001.23456E-18 9876543210 G"))
|
||||
if (strcmp (string, " +009. -1.23456E-18 9876543210 G"))
|
||||
goto Fail;
|
||||
|
||||
rewind (stdout);
|
||||
|
@ -62,10 +62,10 @@ int main (void)
|
|||
if (i != 1)
|
||||
goto Fail3;
|
||||
string [41] = '\0';
|
||||
if (strcmp (string, " +009. -0001.23456E-18 9876543210 G"))
|
||||
if (strcmp (string, " +009. -1.23456E-18 9876543210 G"))
|
||||
goto Fail;
|
||||
|
||||
if (strcmp (sstring, " +009. -0001.23456E-18 9876543210 G\n"))
|
||||
if (strcmp (sstring, " +009. -1.23456E-18 9876543210 G\n"))
|
||||
goto Fail;
|
||||
|
||||
|
||||
|
|
|
@ -35,37 +35,37 @@ int main (void)
|
|||
/* Write formatted output as string to the output files and sstring. */
|
||||
|
||||
i = fprintf (f1, " %0+*.*Le %- 15E %#0 .e E\n", i1, i2, e1, d1, fl1);
|
||||
if (i != 54)
|
||||
if (i != 55)
|
||||
goto Fail;
|
||||
|
||||
i = printf (" %0+*.*Le %- 15E %#0 .e E\n", i1, i2, e1, d1, fl1);
|
||||
if (i != 54)
|
||||
if (i != 55)
|
||||
goto Fail;
|
||||
|
||||
i = sprintf (sstring, " %0+*.*Le %- 15E %#0 .e E\n", i1, i2, e1, d1, fl1);
|
||||
if (i != 54)
|
||||
if (i != 55)
|
||||
goto Fail;
|
||||
|
||||
|
||||
/* Check the string written. */
|
||||
|
||||
rewind (f1);
|
||||
i = fscanf (f1, "%53c", string);
|
||||
i = fscanf (f1, "%54c", string);
|
||||
if (i != 1)
|
||||
goto Fail3;
|
||||
string [53] = '\0';
|
||||
if (strcmp (string, " +1.2345600000000000e-203 -4.700000E+00 5e+00 E"))
|
||||
string [54] = '\0';
|
||||
if (strcmp (string, " +1.2345600000000000e-203 -4.700000E+00 5.e+00 E"))
|
||||
goto Fail;
|
||||
|
||||
rewind (stdout);
|
||||
i = fscanf (stdout, "%53c", string);
|
||||
i = fscanf (stdout, "%54c", string);
|
||||
if (i != 1)
|
||||
goto Fail3;
|
||||
string [53] = '\0';
|
||||
if (strcmp (string, " +1.2345600000000000e-203 -4.700000E+00 5e+00 E"))
|
||||
string [54] = '\0';
|
||||
if (strcmp (string, " +1.2345600000000000e-203 -4.700000E+00 5.e+00 E"))
|
||||
goto Fail;
|
||||
|
||||
if (strcmp (sstring, " +1.2345600000000000e-203 -4.700000E+00 5e+00 E\n"))
|
||||
if (strcmp (sstring, " +1.2345600000000000e-203 -4.700000E+00 5.e+00 E\n"))
|
||||
goto Fail;
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
int main (void)
|
||||
{
|
||||
char sstr [] = " 23 -3.8E20 - e- +25e- 00002.00008e000049.9 ";
|
||||
char sstr [] = " 23 -3.8E20 -0 0e-9 +25e-0 00002.00008e000049.9 ";
|
||||
float f1, f2, f3, f4;
|
||||
double d1, d2, d3;
|
||||
int i;
|
||||
|
|
|
@ -16,7 +16,7 @@ int main (void)
|
|||
f = fopen ("3/tmp", "wb+"); /* open input file for test */
|
||||
if (f == NULL)
|
||||
goto Fail1;
|
||||
fprintf(f, "23 -3.8E20 - e- +25e- 00002.00008e000049.9");
|
||||
fprintf(f, "23 -3.8E20 -0 0e-0 +25e-0 00002.00008e000049.9");
|
||||
fclose(f);
|
||||
|
||||
stdin = freopen ("3/tmp", "r", stdin);
|
||||
|
|
|
@ -14,7 +14,7 @@ int main (void)
|
|||
f = fopen ("3/tmp", "wb+"); /* open input file for test */
|
||||
if (f == NULL)
|
||||
goto Fail1;
|
||||
fprintf(f, "23 -3.8E20 - e- +25e- 00002.00008e000049.9");
|
||||
fprintf(f, "23 -3.8E20 -0 0e-0 +25e-0 00002.00008e000049.9");
|
||||
rewind(f);
|
||||
|
||||
f1 = f2 = f3 = f4 = 1.0;
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
{1} c99pragma.c
|
||||
{1} c99inline.c
|
||||
{1} c99desinit.c
|
||||
{1} c99printfa.c
|
||||
{1} c99strtold.c
|
||||
{1} c99ppnum.c
|
||||
{1} c11generic.c
|
||||
{1} c11align.c
|
||||
{1} c11noret.c
|
||||
|
|
|
@ -155,15 +155,13 @@ int main(void) {
|
|||
expect_exact(cosh(+INFINITY), +INFINITY);
|
||||
expect_exact(coshf(-INFINITY), +INFINITY);
|
||||
expect_overflow(coshl(LDBL_MAX), +INFINITY);
|
||||
feclearexcept(FE_ALL_EXCEPT); // ORCA/C cosh bug workaround
|
||||
expect_approx(coshl(1.0), 1.543080634815243778546L);
|
||||
feclearexcept(FE_ALL_EXCEPT); // ORCA/C cosh bug workaround
|
||||
expect_approx(coshl(-10.0), 11013.23292010332313939L);
|
||||
|
||||
expect_exact(sinh(+0.0), +0.0);
|
||||
expect_exact(sinhf(-0.0), -0.0);
|
||||
//expect_exact(sinh(+INFINITY), +INFINITY); // ORCA/C gives a NAN
|
||||
//expect_exact(sinhf(-INFINITY), -INFINITY); // ORCA/C gives a NAN
|
||||
expect_exact(sinh(+INFINITY), +INFINITY);
|
||||
expect_exact(sinhf(-INFINITY), -INFINITY);
|
||||
expect_approx(sinhl(1.25), 1.601919080300825637951L);
|
||||
expect_approx(sinhl(-20.0), -242582597.704895138042L);
|
||||
|
||||
|
@ -365,6 +363,34 @@ int main(void) {
|
|||
expect_approx(erfcl(9.99L), 2.553157649309533e-45L);
|
||||
expect_approx(erfcl(105.0L), 4.300838032791244e-4791L);
|
||||
|
||||
expect_exact(lgamma(1.0), +0.0);
|
||||
expect_exact(lgammaf(2.0), -0.0);
|
||||
expect_pole_error(lgammal(0.0), +INFINITY);
|
||||
expect_pole_error(lgammal(-0.0), +INFINITY);
|
||||
expect_pole_error(lgammal(-1.0), +INFINITY);
|
||||
expect_pole_error(lgammal(-2.0), +INFINITY);
|
||||
expect_pole_error(lgammal(-3.0), +INFINITY);
|
||||
expect_pole_error(lgammal(-1e50), +INFINITY);
|
||||
expect_pole_error(lgammal(-LDBL_MAX), +INFINITY);
|
||||
expect_exact(lgamma(-INFINITY), +INFINITY);
|
||||
expect_exact(lgammaf(+INFINITY), +INFINITY);
|
||||
expect_approx(lgammal(1e-50L), 1.151292546497022842e+02L);
|
||||
expect_approx(lgammal(0.5L), 5.723649429247000870e-01L);
|
||||
expect_approx(lgammal(0.99L), 5.854806764709776173e-03L);
|
||||
expect_approx(lgammal(1.00000000001L), -5.772156625868682203e-12L);
|
||||
expect_approx(lgammal(1.25L), -9.827183642181316143e-02L);
|
||||
expect_approx(lgammal(1.9999999999L), -4.227843352103923846e-11L);
|
||||
expect_approx(lgammal(2.125L), 5.775985153034387160e-02L);
|
||||
expect_approx(lgammal(3.5L), 1.200973602347074225e+00L);
|
||||
expect_approx(lgammal(1200.75L), 7.310783651998328589e+03L);
|
||||
expect_approx(lgammal(1e4928L), 1.134613933827465713e+4932L);
|
||||
expect_approx(lgammal(-0.00000000001L), 2.532843602294027468e+01L);
|
||||
expect_approx(lgammal(-0.99L), 4.609530213895523164e+00L);
|
||||
expect_approx(lgammal(-1.5L), 8.600470153764810144e-01L);
|
||||
expect_approx(lgammal(-2.000000953674316L), 1.316979555107021760e+01L);
|
||||
expect_approx(lgammal(-5.75L), -4.624612415302172588e+00L);
|
||||
expect_approx(lgammal(-1000000000000.5L), -2.663102111595595344e+13L);
|
||||
|
||||
expect_pole_error(tgamma(+0.0), +INFINITY);
|
||||
expect_pole_error(tgammaf(-0.0), -INFINITY);
|
||||
expect_domain_error(tgammal(-2.0));
|
||||
|
@ -507,14 +533,14 @@ int main(void) {
|
|||
|
||||
expect_exact(fmod(+0.0, 10.0), +0.0);
|
||||
expect_exact(fmodf(-0.0, 10.0), -0.0);
|
||||
//expect_domain_error(fmodl(INFINITY, 10.0)); // no "invalid" in ORCA/C
|
||||
expect_domain_error(fmodl(INFINITY, 10.0));
|
||||
expect_nan(fmodl(INFINITY, 10.0));
|
||||
//expect_domain_error(fmod(1.0, 0.0)); // gives 1 in ORCA/C
|
||||
expect_domain_error(fmod(1.0, 0.0));
|
||||
//expect_exact(fmodl(1.25, +INFINITY), 1.25); //gives NAN in ORCA/C
|
||||
expect_exact(fmodl(11.5, 3.0), 2.5);
|
||||
expect_exact(fmodl(-11.5, 3.0), -2.5);
|
||||
//expect_exact(fmodl(11.5, -3.0), 2.5); // gives -0.5 in ORCA/C
|
||||
//expect_exact(fmodl(-11.5, -3.0), -2.5); // gives -0.5 in ORCA/C
|
||||
expect_exact(fmodl(11.5, -3.0), 2.5);
|
||||
expect_exact(fmodl(-11.5, -3.0), -2.5);
|
||||
|
||||
expect_exact(remainder(+0.0, 10.0), +0.0);
|
||||
expect_exact(remainderf(-0.0, 10.0), -0.0);
|
||||
|
@ -606,10 +632,10 @@ int main(void) {
|
|||
|
||||
expect_exact(strtod("-1.25e+3x", &p), -1250.0); expect_exact(*p, 'x');
|
||||
expect_exact(strtold("-InFin", &p), -INFINITY); expect_exact(*p, 'i');
|
||||
expect_exact(strtof("INFiniTy", &p), INFINITY); //expect_exact(*p, 0);
|
||||
expect_exact(strtof("INFiniTy", &p), INFINITY); expect_exact(*p, 0);
|
||||
expect_nan(strtod("nAN", NULL));
|
||||
expect_nan(strtof("-naN(50)", NULL));
|
||||
//expect_exact(strtold("0xa.8p+2", NULL), 42.0);
|
||||
expect_exact(strtold("0xa.8p+2", NULL), 42.0);
|
||||
|
||||
printf ("Passed Conformance Test c99math\n");
|
||||
return 0;
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Test handling of preprocessing numbers.
|
||||
*
|
||||
* Most of this applies to C89, but hex float and long long are specific to
|
||||
* C99 and later.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COMBINE3(a,b,c) a##b##c
|
||||
#define STRINGIZE(x) #x
|
||||
|
||||
int main(void) {
|
||||
if (COMBINE3(123,.,456) != 123.456)
|
||||
goto Fail;
|
||||
if (COMBINE3(1.,08,999999999999999999999999999999999)
|
||||
!= 1.08999999999999999999999999999999999)
|
||||
goto Fail;
|
||||
if (COMBINE3(0x,AB,09) != 0xAB09)
|
||||
goto Fail;
|
||||
if (strcmp(STRINGIZE(.1xyzp+), ".1xyzp+") != 0)
|
||||
goto Fail;
|
||||
if (strcmp(STRINGIZE(0xaBcD), "0xaBcD") != 0)
|
||||
goto Fail;
|
||||
if (strcmp(STRINGIZE(089ae-.), "089ae-.") != 0)
|
||||
goto Fail;
|
||||
if (sizeof(COMBINE3(123,L,L)) < sizeof(long long))
|
||||
goto Fail;
|
||||
|
||||
printf ("Passed Conformance Test c99ppnum\n");
|
||||
return 0;
|
||||
|
||||
Fail:
|
||||
printf ("Failed Conformance Test c99ppnum\n");
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Test 'a' and 'A' conversions in printf (C99).
|
||||
*
|
||||
* This makes certain assumptions about implementation-defined
|
||||
* behavior like the positioning of bits in hex float output.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <fenv.h>
|
||||
|
||||
#pragma STDC FENV_ACCESS ON
|
||||
|
||||
int main(void) {
|
||||
char buf[100];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.15La %0.10LA", 123.0L, -234.0L);
|
||||
if (strcmp(buf, "0xf.600000000000000p+3 -0XE.A000000000P+4"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "% 10.15La", 123.0L);
|
||||
if (strcmp(buf, " 0xf.600000000000000p+3"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%+ 25.15La", 123.0L);
|
||||
if (strcmp(buf, " +0xf.600000000000000p+3"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.0La %#.0La", 123.0L, 123.0L);
|
||||
if (strcmp(buf, "0xfp+3 0xf.p+3"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%10.0La", 123.0L);
|
||||
if (strcmp(buf, " 0xfp+3"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%0#10.0La", 123.0L);
|
||||
if (strcmp(buf, "0x000f.p+3"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%-010.0La", 123.0L);
|
||||
if (strcmp(buf, "0xfp+3 "))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%La", 0xf.abcdef012345678p-16000L);
|
||||
if (strcmp(buf, "0xf.abcdef012345678p-16000"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%30La", -0xf.abcdef012345678p+16000L);
|
||||
if (strcmp(buf, " -0xf.abcdef012345678p+16000"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.15A", -0.0);
|
||||
if (strcmp(buf, "-0X0.000000000000000P+0"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%010A", -INFINITY);
|
||||
if (strcmp(buf, " -INF"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%A", NAN);
|
||||
if (!strstr(buf, "NAN"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%LA", (long double)LDBL_MAX);
|
||||
if (strcmp(buf, "0XF.FFFFFFFFFFFFFFFP+16380"))
|
||||
goto Fail;
|
||||
|
||||
#ifdef __ORCAC__
|
||||
snprintf(buf, sizeof(buf), "%.10LA", -(long double)LDBL_MAX);
|
||||
if (strcmp(buf, "-0X8.0000000000P+16381"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.14LA", (long double)LDBL_MAX);
|
||||
if (strcmp(buf, "0X8.00000000000000P+16381"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.14LA", 0XF.FFFFFFFFFFFFFF8P+16380L);
|
||||
if (strcmp(buf, "0X8.00000000000000P+16381"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.14LA", 0XF.FFFFFFFFFFFFFF7P+16380L);
|
||||
if (strcmp(buf, "0XF.FFFFFFFFFFFFFFP+16380"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.6LA", 0XF.1234567p-50L);
|
||||
if (strcmp(buf, "0XF.123456P-50"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.6LA", 0XF.1234568p+500L);
|
||||
if (strcmp(buf, "0XF.123456P+500"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.6LA", -0XF.1234569p+5000L);
|
||||
if (strcmp(buf, "-0XF.123457P+5000"))
|
||||
goto Fail;
|
||||
|
||||
fesetround(FE_UPWARD);
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.14LA", 0XF.FFFFFFFFFFFFFF7P+16380L);
|
||||
if (strcmp(buf, "0X8.00000000000000P+16381"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.14LA", -0XF.FFFFFFFFFFFFFF7P+16380L);
|
||||
if (strcmp(buf, "-0XF.FFFFFFFFFFFFFFP+16380"))
|
||||
goto Fail;
|
||||
|
||||
fesetround(FE_DOWNWARD);
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.14LA", -0XF.FFFFFFFFFFFFFF7P+16380L);
|
||||
if (strcmp(buf, "-0X8.00000000000000P+16381"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.14LA", 0XF.FFFFFFFFFFFFFF7P+16380L);
|
||||
if (strcmp(buf, "0XF.FFFFFFFFFFFFFFP+16380"))
|
||||
goto Fail;
|
||||
|
||||
fesetround(FE_TOWARDZERO);
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.14LA", -0XF.FFFFFFFFFFFFFF7P+16380L);
|
||||
if (strcmp(buf, "-0XF.FFFFFFFFFFFFFFP+16380"))
|
||||
goto Fail;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%.14LA", 0XF.FFFFFFFFFFFFFF7P+16380L);
|
||||
if (strcmp(buf, "0XF.FFFFFFFFFFFFFFP+16380"))
|
||||
goto Fail;
|
||||
|
||||
fesetround(FE_TONEAREST);
|
||||
|
||||
snprintf(buf, sizeof(buf), "%La", (long double)0x1p-16445);
|
||||
if (strcmp(buf, "0x0.000000000000002p-16386"))
|
||||
goto Fail;
|
||||
#endif
|
||||
|
||||
printf ("Passed Conformance Test c99printfa\n");
|
||||
return 0;
|
||||
|
||||
Fail:
|
||||
|
||||
printf ("Failed Conformance Test c99printfa\n");
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Test strtold function (C99).
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <fenv.h>
|
||||
|
||||
#pragma STDC FENV_ACCESS ON
|
||||
|
||||
void fail(void) {
|
||||
printf ("Failed Conformance Test c99strtold\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void test(const char *str, long double val, size_t len, int err) {
|
||||
char *endptr;
|
||||
long double result;
|
||||
|
||||
errno = 0;
|
||||
result = strtold(str, &endptr);
|
||||
if (err >= 0 && errno != err)
|
||||
fail();
|
||||
if (endptr-str != len)
|
||||
fail();
|
||||
if (!isnan(val)) {
|
||||
if (result != val || !!signbit(result) != !!signbit(val))
|
||||
fail();
|
||||
} else {
|
||||
if (!isnan(result))
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
test("1", 1.0L, 1, 0);
|
||||
test("-2.25E-7", -2.25E-7L, 8, 0);
|
||||
test("InfiniTy", +INFINITY, 8, 0);
|
||||
test("-inFinitx", -INFINITY, 4, 0);
|
||||
test("NaN", NAN, 3, 0);
|
||||
test(" -nan(123)", NAN, 10, 0);
|
||||
test("nan(abC_123)", NAN, 12, 0);
|
||||
test("nan(abC_123-)", NAN, 3, 0);
|
||||
test("nan(123", NAN, 3, 0);
|
||||
test("\t+Nan()", NAN, 7, 0);
|
||||
test("-0xF.8p-1", -7.75L, 9, 0);
|
||||
test(" +0XAB4fp2", 175420.0L, 10, 0);
|
||||
test("0X.23423p-1", 0X.23423p-1L, 11, 0);
|
||||
test("0x4353.p+7", 2206080.0L, 10, 0);
|
||||
test("0xabcdef0012345678ffffffffffffp123",
|
||||
3.7054705751091077761e+70L, 34, 0);
|
||||
test("0xabcdef0012345678000000000000p123",
|
||||
3.7054705751091077758e+70L, 34, 0);
|
||||
test("0x0.0000000000000000000000012345aP50",
|
||||
1.61688425235478883124e-14L, 36, 0);
|
||||
test("0x1324124.abcd23p-3000", 1.63145601325652579262e-896L, 22, 0);
|
||||
test("0x0000000000.000000p1234567890123456789012345678901234567890",
|
||||
0.0, 60, 0);
|
||||
test("0X1p17000", INFINITY, 9, ERANGE);
|
||||
test("0x1.fffffffffffffffep16383",
|
||||
1.18973149535723176502e+4932L, 26, 0);
|
||||
test("0x1.ffffffffffffffffp16383", INFINITY, 26, ERANGE);
|
||||
test("0X1p-16400L", 1.28254056667789211512e-4937L, 10, -1);
|
||||
test("0x3abd.232323p-16390", 1.97485962609712244075e-4930L, 20, 0);
|
||||
test("0x7.7p-17000", 0.0, 12, -1);
|
||||
test("+0x1.8p+", 1.5L, 6, 0);
|
||||
test(" \t\f\n\r\v1.25---", 1.25, 10, 0);
|
||||
test("0x.p50", 0.0, 1, 0);
|
||||
test(" +abc", 0.0, 0, -1);
|
||||
test("-0", -0.0, 2, 0);
|
||||
test("-0x0p123", -0.0, 8, 0);
|
||||
|
||||
fesetround(FE_UPWARD);
|
||||
test("0x8.0000000000000008", 0x8.000000000000001p0L, 20, 0);
|
||||
test("0x8.0000000000000009", 0x8.000000000000001p0L, 20, 0);
|
||||
test("0x8.0000000000000018", 0x8.000000000000002p0L, 20, 0);
|
||||
test("-0x8.0000000000000008", -0x8.000000000000000p0L, 21, 0);
|
||||
test("-0x8.0000000000000009", -0x8.000000000000000p0L, 21, 0);
|
||||
test("-0x8.0000000000000018", -0x8.000000000000001p0L, 21, 0);
|
||||
test("0x8.00000000000000080001", 0x8.000000000000001p0L, 24, 0);
|
||||
|
||||
fesetround(FE_DOWNWARD);
|
||||
test("0x8.0000000000000008", 0x8.000000000000000p0L, 20, 0);
|
||||
test("0x8.0000000000000009", 0x8.000000000000000p0L, 20, 0);
|
||||
test("0x8.0000000000000018", 0x8.000000000000001p0L, 20, 0);
|
||||
test("-0x8.0000000000000008", -0x8.000000000000001p0L, 21, 0);
|
||||
test("-0x8.0000000000000009", -0x8.000000000000001p0L, 21, 0);
|
||||
test("-0x8.0000000000000018", -0x8.000000000000002p0L, 21, 0);
|
||||
test("0x8.00000000000000080001", 0x8.000000000000000p0L, 24, 0);
|
||||
|
||||
fesetround(FE_TOWARDZERO);
|
||||
test("0x8.0000000000000008", 0x8.000000000000000p0L, 20, 0);
|
||||
test("0x8.0000000000000009", 0x8.000000000000000p0L, 20, 0);
|
||||
test("0x8.0000000000000018", 0x8.000000000000001p0L, 20, 0);
|
||||
test("-0x8.0000000000000008", -0x8.000000000000000p0L, 21, 0);
|
||||
test("-0x8.0000000000000009", -0x8.000000000000000p0L, 21, 0);
|
||||
test("-0x8.0000000000000018", -0x8.000000000000001p0L, 21, 0);
|
||||
test("0x8.00000000000000080001", 0x8.000000000000000p0L, 24, 0);
|
||||
|
||||
fesetround(FE_TONEAREST);
|
||||
test("0x8.0000000000000008", 0x8.000000000000000p0L, 20, 0);
|
||||
test("0x8.0000000000000009", 0x8.000000000000001p0L, 20, 0);
|
||||
test("0x8.0000000000000018", 0x8.000000000000002p0L, 20, 0);
|
||||
test("-0x8.0000000000000008", -0x8.000000000000000p0L, 21, 0);
|
||||
test("-0x8.0000000000000009", -0x8.000000000000001p0L, 21, 0);
|
||||
test("-0x8.0000000000000018", -0x8.000000000000002p0L, 21, 0);
|
||||
test("0x8.00000000000000080001", 0x8.000000000000001p0L, 24, 0);
|
||||
|
||||
printf ("Passed Conformance Test c99strtold\n");
|
||||
return 0;
|
||||
}
|
|
@ -5,9 +5,7 @@
|
|||
void main(void)
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 4/0;
|
||||
static int i = 4/0;
|
||||
|
||||
printf("Failed Deviance Test 7.6.1.2\n");
|
||||
}
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
void main(void)
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 4%0;
|
||||
static int i = 4%0;
|
||||
|
||||
printf("Failed Deviance Test 7.6.1.3\n");
|
||||
}
|
||||
|
|
177
cc.notes
177
cc.notes
|
@ -1,10 +1,14 @@
|
|||
ORCA/C 2.2.0 B7
|
||||
ORCA/C 2.2.1
|
||||
Copyright 1997, Byte Works Inc.
|
||||
Updated by Stephen Heumann and Kelvin Sherlock, 2017-2023
|
||||
Updated by Stephen Heumann and Kelvin Sherlock, 2017-2024
|
||||
|
||||
These release notes document the changes between ORCA/C 2.0 and ORCA/C 2.2.1. They are intended mainly for users familiar with earlier versions of ORCA/C. New users should refer to the ORCA/C 2.2 manual, which has been fully updated to document the new features and other changes in ORCA/C 2.2.
|
||||
|
||||
-- Change List --------------------------------------------------------------
|
||||
|
||||
2.2.0 B7 1. Bugs squashed. See bug notes, below.
|
||||
2.2.1 1. Bugs squashed. See bug notes, below.
|
||||
|
||||
2.2.0 1. Bugs squashed. See bug notes, below.
|
||||
|
||||
2. New language features added (mainly features from C99 and C11).
|
||||
See "New Language Features," below.
|
||||
|
@ -58,6 +62,8 @@ Updated by Stephen Heumann and Kelvin Sherlock, 2017-2023
|
|||
|
||||
19. The code generated for certain operations has been improved.
|
||||
|
||||
20. The slot parameter to #pragma float now sets the FPE slot.
|
||||
|
||||
2.1.1 B3 1. Bugs squashed. See bug notes, below.
|
||||
|
||||
2.1.0 1. Bugs squashed. See bug notes, below.
|
||||
|
@ -82,7 +88,9 @@ Updated by Stephen Heumann and Kelvin Sherlock, 2017-2023
|
|||
|
||||
2.0.1 1. Bugs squashed. See bug notes, below.
|
||||
|
||||
-- Manual Errata ------------------------------------------------------------
|
||||
-- Manual Errata in the ORCA/C 2.0 Manual -----------------------------------
|
||||
|
||||
(These errata have been corrected in the ORCA/C 2.2 manual.)
|
||||
|
||||
p. 40
|
||||
|
||||
|
@ -197,6 +205,8 @@ If precompiled headers are being used, #pragma expand will not print the tokens
|
|||
|
||||
p. 258
|
||||
|
||||
The slot parameter to #pragma float is now optional, and if present is used to set the FPE slot. See "Changes to #pragma float," below.
|
||||
|
||||
The #pragma ignore directive supports several new bits.
|
||||
|
||||
Bit 1 affects the interpretation of multi-character character constants. See "Multi-Character Character Constants," below.
|
||||
|
@ -317,10 +327,6 @@ p. 352
|
|||
|
||||
If a dup() call is successful, it actually returns the new file ID (a non-negative integer).
|
||||
|
||||
p. 355
|
||||
|
||||
If an fcntl() call using F_DUPFD is successful, it actually returns the new file ID (a non-negative integer).
|
||||
|
||||
p. 353
|
||||
|
||||
All error numbers used by errno are defined in <errno.h>, not <math.h>.
|
||||
|
@ -331,6 +337,10 @@ p. 354
|
|||
|
||||
The discussion of abort() should note that it will call raise(SIGABRT) before exiting. Accordingly, if a SIGABRT handler was previously registered via a call to signal(), it will be executed.
|
||||
|
||||
p. 355
|
||||
|
||||
If an fcntl() call using F_DUPFD is successful, it actually returns the new file ID (a non-negative integer).
|
||||
|
||||
p. 356
|
||||
|
||||
fgetpos() and fsetpos() actually set errno to EIO if there is an error.
|
||||
|
@ -545,7 +555,7 @@ The CX_LIMITED_RANGE pragma relates to complex arithmetic, which ORCA/C does not
|
|||
type-name ':' assignment-expression |
|
||||
default ':' assignment-expression
|
||||
|
||||
The generic-assoc-list provides a list of associations of types with expressions (and optionally a default association). If the type of the the initial expression is compatible with one of those in the generic-assoc-list, the generic selection expression evaluates to the expression specified in that association. If there is no compatible type but there is a default association, the expression specified there is used. It is an error if there is no suitable association. Only the expression from the selected association is evaluated and becomes the value of the overall generic selection expression; the initial expression and all those in other associations are not evaluated.
|
||||
The generic-assoc-list provides a list of associations of types with expressions (and optionally a default association). If the type of the initial expression is compatible with one of those in the generic-assoc-list, the generic selection expression evaluates to the expression specified in that association. If there is no compatible type but there is a default association, the expression specified there is used. It is an error if there is no suitable association. Only the expression from the selected association is evaluated and becomes the value of the overall generic selection expression; the initial expression and all those in other associations are not evaluated.
|
||||
|
||||
As an example, this expression evaluates to 2 because the type of 1+2 is int:
|
||||
|
||||
|
@ -555,7 +565,9 @@ Generic selection expressions are primarily useful within macros, which can give
|
|||
|
||||
23. (C11) Character constants and string literals may now have prefixes indicating they should use Unicode encodings. The prefixes u8, u, and U indicate UTF-8, UTF-16, and UTF-32 encodings, respectively. The u8 prefix may only be used on string literals. The U and u prefixes may be used on string literals or character constants. U- and u-prefixed character constants have the types char32_t and char16_t (as defined in <uchar.h>); U- and u-prefixed string literals are treated as arrays of those types. For example, the string literal U"abc" designates an array with four members of type char32_t: the three letters encoded in UTF-32, plus a null terminator.
|
||||
|
||||
24. (C99) Floating-point constants may now be expressed in a hexadecimal format. These consist of a leading 0X or 0x, followed by a sequence of hexadecimal digits optionally containing a period, then P or p, then an exponent expressed as a sequence of decimal digits optionally preceded by + or -. These designate the number given by the hexadecimal digit sequence (with any digits after the period being the fractional part) multiplied by 2 raised to the specified exponent. For example, the constant 0xF.8p-1 is equivalent to 7.75. Note that ORCA/C currently only supports this hexadecimal floating-point format in C source code, not as an input or output format for any library functions.
|
||||
24. (C99) Floating-point constants may now be expressed in a hexadecimal format. These consist of a leading 0X or 0x, followed by a sequence of hexadecimal digits optionally containing a period, then P or p, then an exponent expressed as a sequence of decimal digits optionally preceded by + or -. These designate the number given by the hexadecimal digit sequence (with any digits after the period being the fractional part) multiplied by 2 raised to the specified exponent. For example, the constant 0xF.8p-1 is equivalent to 7.75.
|
||||
|
||||
Note that the fprintf family of functions also support output in this hexadecimal floating-point format using the 'A' and 'a' conversion specifiers, described below. The strtod, strtold, and strtof functions can also accept numbers in this format as input.
|
||||
|
||||
25. (C99) When a function parameter is declared with an array type, type qualifiers and/or the keyword "static" may be included within the angle brackets that designate the array type. For example, a function may be defined as:
|
||||
|
||||
|
@ -678,6 +690,14 @@ ORCA/C can perform certain optimizations on floating-point computations based on
|
|||
A new #pragma optimize bit has now been introduced to control this behavior. Setting bit 7 (a value of 128) allows floating-point math optimizations that may violate the IEEE standard. It currently only has an effect if #pragma optimize bit 0 or bit 4 is also set. If bit 7 is not set, these floating-point optimizations will not be performed. This allows most aspects of intermediate code peephole optimization and common subexpression elimination to be used while preserving IEEE floating-point behavior.
|
||||
|
||||
|
||||
Changes to #pragma float
|
||||
------------------------
|
||||
|
||||
The second numeric parameter to #pragma float is now optional. If it is provided, it specifies the slot number of the FPE card. If it is not provided or is not in the range 1-7, the FPE card is auto-detected instead. With these changes, it is generally no longer necessary to call setfpeslot() in programs that use the FPE card.
|
||||
|
||||
If you use #pragma float in any of the special types of programs that can be created using other pragmas, the slot parameter will be ignored and the FPE will not be auto-detected. In those cases, the program will still need to call setfpeslot() to set the slot number before doing any floating-point operations.
|
||||
|
||||
|
||||
Additions to #pragma ignore
|
||||
---------------------------
|
||||
|
||||
|
@ -913,7 +933,7 @@ int vsnprintf(char * restrict s, size_t n, const char * restrict format,
|
|||
|
||||
These are equivalent to sprintf and vsprintf, except that they take an additional argument giving the maximum number of characters to be written. If n is 0, no characters are written. Otherwise, at most n-1 characters are written based on the format string, followed by a terminating null character. They return the number of characters (not including the terminating null character) that would have been written if there was no size limit.
|
||||
|
||||
3. (C99) The vscanf(), vfscanf(), anf vsscanf() functions have been added:
|
||||
3. (C99) The vscanf(), vfscanf(), and vsscanf() functions have been added:
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
@ -927,7 +947,11 @@ These functions are equivalent to scanf, fscanf, and sscanf, except that the var
|
|||
|
||||
The length modifiers 'z', 't', 'j', 'hh', and 'll' are now allowed in the format strings for the fprintf and fscanf families of functions. They may be used with the 'd', 'i', 'o', 'u', 'x', 'X', or 'n' conversion specifiers. These each correspond to integer types, as follows: 'z' to size_t or the corresponding signed integer type, 't' to ptrdiff_t or the corresponding unsigned integer type, 'j' to intmax_t or uintmax_t, 'hh' to signed char or unsigned char, and 'll' to long long or unsigned long long. The corresponding argument must be an integer of an appropriate type, or a pointer to such an integer, as appropriate for the function and conversion specifier.
|
||||
|
||||
The conversion specifiers 'F', 'a', and 'A' are now allowed in the format strings for the fscanf family of functions. These are all equivalent to 'f' (but none of them accept numbers in the hexadecimal format allowed by C99). The 'F' conversion specifier is also now allowed in the format strings for the fprintf family of functions. It is equivalent to 'f', except that "INF" and "NAN" are guaranteed to be printed in upper case. The conversion specifiers 'a' and 'A' (both also used with floating-point numbers) are also recognized in the format strings for the fprintf family of functions, but they do not currently print the numbers in the hexadecimal format required by the C99 standard.
|
||||
The conversion specifiers 'a' and 'A' are now allowed in the format strings for the fprintf family of functions. The 'a' specifier consumes an argument of type double or long double and writes the value in a hexadecimal exponential format. It consists of a leading sign (if negative or required by the flags used), then '0x', then a number in hexadecimal format (with one hexadecimal digit for the integer part, then a dot and fractional digits), then 'p', then a signed decimal number giving the exponent of 2. If a precision is specified, it gives the number of digits after the dot; if not, enough digits are used to exactly represent the number. If the precision is 0 and the '#' flag is not used, no dot is printed. The 'A' specifier is equivalent to 'a', except that all letters are output in upper case.
|
||||
|
||||
The conversion specifier 'F' is now allowed in the format strings for the fprintf family of functions. It is equivalent to 'f', except that "INF" and "NAN" are guaranteed to be printed in upper case.
|
||||
|
||||
The conversion specifiers 'F', 'a', and 'A' are also allowed in the format strings for the fscanf family of functions. These are all equivalent to 'f' (but none of them accept numbers in the hexadecimal format described above).
|
||||
|
||||
The ORCA/C-specific conversion specifier 'P' is now allowed in the format strings for the fprintf and fscanf families of functions. This works exactly the same as the existing 'b' conversion specifier, printing or reading input to a string with a leading length byte (a p-string). This new specifier was introduced because the 'b' specifier may be used for a different purpose in future C standards. For the time being, the 'b' specifier is still available with its existing meaning, but it is considered deprecated. Code should be migrated to use the 'P' conversion specifier instead.
|
||||
|
||||
|
@ -1252,6 +1276,13 @@ int ilogbl(long double x);
|
|||
|
||||
These functions extract the binary exponent of x as an integer value, treating denormalized numbers as if they were normalized. If x is 0, infinite, or NaN, they return the macro values FP_ILOGB0, INT_MAX, or FP_ILOGBNAN, respectively.
|
||||
|
||||
#include <math.h>
|
||||
double lgamma(double x);
|
||||
float lgammaf(float x);
|
||||
long double lgammal(long double x);
|
||||
|
||||
These functions compute the natural logarithm of the absolute value of the gamma function of x.
|
||||
|
||||
#include <math.h>
|
||||
double log1p(double x);
|
||||
float log1pf(float x);
|
||||
|
@ -1410,14 +1441,6 @@ long double tanhl(long double x);
|
|||
|
||||
These functions are equivalent to the existing un-suffixed versions, apart from their argument and return types. In ORCA/C, most of them actually behave identically to the un-suffixed versions. An exception is the modf family of functions, which differ in the type of the location in which the integer part of the value is stored.
|
||||
|
||||
Similarly, there are float and long double analogs of the string conversion function strtod:
|
||||
|
||||
#include <stdlib.h>
|
||||
float strtof(const char * restrict str, char ** restrict ptr);
|
||||
long double strtold(const char * restrict str, char ** restrict ptr);
|
||||
|
||||
As currently implemented in ORCA/C, strtof and strtold behave identically to strtod, all giving values with the precision and range of long double.
|
||||
|
||||
20. Several <time.h> functions can now use the Time Tool Set by Geoff Weiss to determine the time zone. This behavior is controlled by a new variable:
|
||||
|
||||
#include <time.h>
|
||||
|
@ -1448,6 +1471,18 @@ The only time base supported by ORCA/C is TIME_UTC. This gives the time in seco
|
|||
|
||||
Although struct timespec can represent a time with nanosecond resolution, ORCA/C currently only reports the time with a resolution of one second, so ts->tv_nsec is always set to 0.
|
||||
|
||||
22. (C99) The strtod function can now accept strings in a hexadecimal floating-point format, in addition to the normal decimal format. The hexadecimal format consists of an optional leading + or - sign, then 0X or 0x, then a sequence of hexadecimal digits optionally containing a period, then an optional exponent part consisting of a P or p character followed by a decimal number optionally preceded by + or -. A string in this format designates the number given by the sign (if present) and the hexadecimal digit sequence (with any digits after the period being the fractional part) multiplied by 2 raised to the specified exponent (if it is present). For example, "0xF.8p-1" designates the number 7.75.
|
||||
|
||||
The strtod function also accepts the string "INFINITY" (without regard to case, and optionally preceded by + or -) to designate an infinity. This is equivalent to the string "INF", which was already accepted in earlier versions of ORCA/C.
|
||||
|
||||
Also, there are now float and long double analogs of the strtod function:
|
||||
|
||||
#include <stdlib.h>
|
||||
float strtof(const char * restrict str, char ** restrict ptr);
|
||||
long double strtold(const char * restrict str, char ** restrict ptr);
|
||||
|
||||
As currently implemented in ORCA/C, strtof and strtold behave identically to strtod, all giving values with the precision and range of long double.
|
||||
|
||||
-- Compiler changes introduced in C 2.1.0 -----------------------------------
|
||||
|
||||
The Default .h File
|
||||
|
@ -1549,6 +1584,50 @@ Turning this optimization on means ORCA/C is no longer strictly in compliance wi
|
|||
|
||||
If you use #pragma debug 0x0010 to enable stack check debug code, the compiler will still flag variable argument functions that do not consume all arguments as a run-time error, even though ANSI C does allow them.
|
||||
|
||||
-- Bugs from C 2.2.0 that have been fixed in C 2.2.1 ------------------------
|
||||
|
||||
1. If there was a #define directive immediately after the opening brace of a function body, and the macro defined there was used after the end of that function or was used in the initializer for a static variable, incorrect code might be generated or spurious errors might be reported.
|
||||
|
||||
(Kelvin Sherlock)
|
||||
|
||||
2. In <gsbug.h>, the declarations of the pseudo tool calls provided by GSBug did not include prototypes. Now they do.
|
||||
|
||||
(Kelvin Sherlock)
|
||||
|
||||
3. In <gsos.h>, the error code devListFull was misspelled as defListFull.
|
||||
|
||||
4. Code that divides an integer constant by zero (e.g. 1/0) will no longer always produce an error. Such code will produce undefined behavior if it is executed, but since the compiler cannot always determine whether the code will be executed at run time, this is no longer treated as an error that prevents compilation. If #pragma lint bit 5 is set, a lint message about the division by zero will still be produced. An error will also still be reported for division by zero in constant expressions that need to be evaluated at compile time.
|
||||
|
||||
5. In some obscure circumstances, ORCA/C might behave incorrectly when the postfix ++ or -- operators were used on an expression of pointer type. This would typically result in "compiler error" messages, but could potentially also cause incorrect code to be generated without any errors being reported.
|
||||
|
||||
6. If the first string passed to strcat() or strncat() crossed a bank boundary, those functions would generally behave incorrectly and corrupt memory.
|
||||
|
||||
7. In certain situations where the third argument to strncat() was 0x8000 or greater, it could behave incorrectly.
|
||||
|
||||
8. If strncmp() was called with a third argument of 0x1000000 or greater, it could sometimes incorrectly return 0. (Note that such size values exceed the address space of the 65816, so under ORCA/C they effectively impose no limit on the number of characters to be compared. The behavior of strncmp() should therefore be the same as strcmp() in these cases.)
|
||||
|
||||
9. If an error was encountered when trying to write out buffered data in fclose(), the stream would not actually be closed, and the buffer allocated for it would not be freed. Now the stream will be closed (disassociated from the file) and the buffer will be freed even if an error is encountered.
|
||||
|
||||
10. If an error was encountered when trying to write out buffered data to a file when exiting the program, it could hang and never actually quit.
|
||||
|
||||
11. If fclose() was called on a file created by tmpfile() at a time when there was very little free memory available, it could corrupt memory and cause a crash. (This will no longer happen, but the file still may not be deleted if there is insufficient memory available when fclose() is called.)
|
||||
|
||||
12. If a numeric token formed using a ## preprocessor operator was an operand for another ## preprocessor operator, the resulting token would be incorrect.
|
||||
|
||||
13. If an empty argument was passed for a macro parameter that was used as an operand of the ## preprocessing operator, the result would likely be incorrect, and subsequent uses of the same macro also might not be expanded correctly.
|
||||
|
||||
14. If a struct, union, or enum type name appeared within the third expression in a for loop statement (e.g. in a cast or as the argument to sizeof), ORCA/C could behave incorrectly. It could report a spurious error if a semicolon occurred within the type name as part of a structure or union member declaration. Also, any tags or enumeration constants declared by such a type name should be in scope within the loop body, but they were not.
|
||||
|
||||
15. Native code peephole optimization might produce invalid code in some obscure circumstances where one element of a global or static array was decremented and then another element of the same array was accessed immediately thereafter.
|
||||
|
||||
16. When an expression of const- or volatile-qualified struct or union type was passed as a function parameter, incorrect code would be generated. This could lead to incorrect program behavior or crashes.
|
||||
|
||||
17. Incorrect code could be generated in certain circumstances where a long long or unsigned long long member of a structure or array was accessed via a pointer.
|
||||
|
||||
18. The ORCA/C preprocessor now allows for preprocessing number tokens that do not match the syntax of an integer or floating constant (e.g. 08Ae-.x). If any such tokens remain after preprocessing, an error will still be reported. Note that this means that code like 0x3e+1 is now treated as a single token that is invalid if it remains after preprocessing, rather than as three tokens that form a valid expression; if you want it to be interpreted as three tokens, you must include whitespace before the +.
|
||||
|
||||
19. When numeric tokens beginning with . were used as operands to the ## preprocessing operator, they behaved as if they started with a leading 0, which could lead to an incorrect result (e.g. 123##.456 became 1230.456).
|
||||
|
||||
-- Bugs from C 2.1.1 B3 that have been fixed in C 2.2.0 ---------------------
|
||||
|
||||
1. There were various bugs that could cause incorrect code to be generated in certain cases. Some of these were specific to certain optimization passes, alone or in combination.
|
||||
|
@ -2162,6 +2241,64 @@ int foo(int[42]);
|
|||
|
||||
241. When using the large memory model, functions registered with atexit() (or at_quick_exit(), in ORCA/C 2.2 betas) might be called with the data bank set incorrectly, potentially causing memory corruption or other incorrect behavior.
|
||||
|
||||
(Bug fixes below here were added in the final release of ORCA/C 2.2.0.)
|
||||
|
||||
242. In the fprintf() family of functions, the '0' flag should be ignored if '-' was also specified.
|
||||
|
||||
243. In the fprintf() family of functions, when a conversion specification like "%#.0o" is used with the value 0, it should print "0" (rather than nothing).
|
||||
|
||||
244. Calls to malloc(), calloc(), or realloc() with a requested allocation size of 2 GB or greater could sometimes return a non-null pointer. Such calls should always fail and return NULL, since the IIGS does not have that much memory.
|
||||
|
||||
245. Programs using #pragma rtl would not return the proper value if run from the shell. (This did not affect the usual use of #pragma rtl for a PIF or TIF.)
|
||||
|
||||
246. The difftime() function would return incorrect values if the two times were at least 2^31 seconds (about 68 years) apart.
|
||||
|
||||
247. Floating-point conversions in the scanf() family of functions should scan to a long double if the L modifier is used, but this did not work properly.
|
||||
|
||||
(Kelvin Sherlock)
|
||||
|
||||
248. If the low-order 16 bits of the size passed realloc() were 0x0001, it would fail to deallocate the memory at the old address. This might cause the system to run out of memory.
|
||||
|
||||
249. In certain obscure circumstances, realloc() might access soft switches or slot I/O locations, which could cause strange behavior or crashes.
|
||||
|
||||
250. When using the E conversion specifier in the fprintf() family of functions, INF or NAN values might not be printed correctly. The output for them could have incorrect padding and/or extraneous characters at the end.
|
||||
|
||||
251. When a conversion specification like %#.0E or %#.0e is used in the fprintf() family of functions, the printed number should include a decimal point.
|
||||
|
||||
252. When using the g or G conversion specifiers in the fprintf() family of functions, slightly incorrect limits were used for determining whether to print the value in a decimal or exponential format.
|
||||
|
||||
253. When using the g or G conversion specifiers in the fprintf() family of functions, too many or too few digits might be printed in some circumstances, or a trailing decimal point might be printed when it should not be.
|
||||
|
||||
(Devin Reade)
|
||||
|
||||
254. The strtod() function should be able to skip over line feed, form feed, carriage return, and vertical tab characters (as well as space and horizontal tab) as part of the whitespace that may precede the number.
|
||||
|
||||
255. The strtod() function should return 0 if the string is empty or is not in the expected format.
|
||||
|
||||
(Dave Tribby)
|
||||
|
||||
256. In the fscanf() family of functions, floating-point conversions like %f could match certain character sequences that were not in the proper format, e.g. because they contained no digits.
|
||||
|
||||
257. In the fscanf() family of functions, an input failure caused by encountering EOF should cause any subsequent directives to be skipped and not executed, even if they are directives like %n that require no input.
|
||||
|
||||
258. If scanf() was called with a format string that was empty or contained only %n directives, it might pause awaiting a line of input from the console. It should not do this, because it should not try to read any characters for such calls.
|
||||
|
||||
259. If an error was encountered when processing a floating-point conversion directive with assignment suppressed, the scanf() family of functions might not return the correct value.
|
||||
|
||||
260. When using the g or G conversion specifiers in the fprintf() family of functions, the number zero could sometimes be printed in an exponential format like "0e+00". It should be printed in a non-exponential format like "0".
|
||||
|
||||
261. Several <math.h> functions could set errno inappropriately, based on a previous floating-point math operation rather than the current operation.
|
||||
|
||||
262. If a domain or range error had occurred in any previous floating-point operation, sinh() and cosh() calls might return the wrong values.
|
||||
|
||||
(William K. Watts, Jr.)
|
||||
|
||||
263. The sqrt() function would set errno to ERANGE if its argument was negative. This is a domain error, so it should set errno to EDOM in this case.
|
||||
|
||||
(William K. Watts, Jr.)
|
||||
|
||||
264. The fmod() function could return the wrong value when the second argument was negative.
|
||||
|
||||
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
|
||||
|
||||
1. In some situations, fread() reread the first 1K or so of the file.
|
||||
|
|
73
settypes
73
settypes
|
@ -1,20 +1,61 @@
|
|||
filetype = src
|
||||
change =.rez rez
|
||||
change =.pas pascal
|
||||
change =.Comments pascal
|
||||
change =.Debug pascal
|
||||
change =.Print pascal
|
||||
change =.asm asm65816
|
||||
change =.macros asm65816
|
||||
change make= exec
|
||||
change linkit= linker
|
||||
change smake exec
|
||||
change count exec
|
||||
change backup exec
|
||||
change settypes exec
|
||||
filetype =.notes txt
|
||||
filetype =.md txt
|
||||
filetype -p =.rez= src; change -p =.rez= rez
|
||||
filetype -p =.pas src; change -p =.pas pascal
|
||||
filetype CGI.Comments src; change CGI.Comments pascal
|
||||
filetype CGI.Debug src; change -p CGI.Debug pascal
|
||||
filetype Scanner.debug src; change -p Scanner.debug pascal
|
||||
filetype Symbol.Print src; change Symbol.Print pascal
|
||||
filetype -p =.asm src; change -p =.asm asm65816
|
||||
filetype -p =.macros src; change -p =.macros asm65816
|
||||
filetype -p make= src; change -p make= exec
|
||||
filetype -p linkit= src; change -p linkit= linker
|
||||
filetype smake src; change smake exec
|
||||
filetype count src; change count exec
|
||||
filetype backup src; change backup exec
|
||||
filetype settypes src; change settypes exec
|
||||
filetype cc.notes txt
|
||||
filetype -p =.md txt
|
||||
filetype LICENSE txt
|
||||
filetype C.Read.Me txt
|
||||
filetype C.Update.ReadMe txt
|
||||
filetype Tech.Support txt
|
||||
filetype Manual.docx $00
|
||||
filetype obj:README.txt txt
|
||||
filetype -p ORCACDefs:=.h src; change -p ORCACDefs:=.h cc
|
||||
filetype -p C.Samples:Benchmarks:=.cc src; change -p C.Samples:Benchmarks:=.cc cc
|
||||
filetype -p C.Samples:CDA.Samples:=.cc src; change -p C.Samples:CDA.Samples:=.cc cc
|
||||
filetype -p C.Samples:CDev.Samples:=.cc src; change -p C.Samples:CDev.Samples:=.cc cc
|
||||
filetype -p C.Samples:CDev.Samples:=.rez src; change -p C.Samples:CDev.Samples:=.rez rez
|
||||
filetype -p C.Samples:CDev.Samples:=.make src; change -p C.Samples:CDev.Samples:=.make exec
|
||||
filetype -p C.Samples:Desktop.Samples:=.cc src; change -p C.Samples:Desktop.Samples:=.cc cc
|
||||
filetype -p C.Samples:Graphic.Samples:=.cc src; change -p C.Samples:Graphic.Samples:=.cc cc
|
||||
filetype -p C.Samples:HyperCard:=.cc src; change -p C.Samples:HyperCard:=.cc cc
|
||||
filetype -p C.Samples:HyperCard:=.rez src; change -p C.Samples:HyperCard:=.rez rez
|
||||
filetype -p C.Samples:HyperCard:=.make src; change -p C.Samples:HyperCard:=.make exec
|
||||
filetype -p C.Samples:HyperStudio:=.cc src; change -p C.Samples:HyperStudio:=.cc cc
|
||||
filetype -p C.Samples:HyperStudio:=.rez src; change -p C.Samples:HyperStudio:=.rez rez
|
||||
filetype -p C.Samples:HyperStudio:=.make src; change -p C.Samples:HyperStudio:=.make exec
|
||||
filetype -p C.Samples:Text.Samples:=.cc src; change -p C.Samples:Text.Samples:=.cc cc
|
||||
filetype -p C.Samples:Text.Samples:=.h src; change -p C.Samples:Text.Samples:=.h cc
|
||||
filetype C.Samples:Text.Samples:Key2.Funcs src; change C.Samples:Text.Samples:Key2.Funcs cc
|
||||
filetype -p C.Samples:Text.Samples:=.asm src; change -p C.Samples:Text.Samples:=.asm asm65816
|
||||
filetype -p C.Samples:Text.Samples:=.Build src; change -p C.Samples:Text.Samples:=.Build exec
|
||||
filetype -p Tests:Conformance:=.c src; change -p Tests:Conformance:=.c cc
|
||||
filetype -p Tests:Conformance:=.CC src; change -p Tests:Conformance:=.CC cc
|
||||
filetype -p Tests:Conformance:DOIT= src; change -p Tests:Conformance:DOIT= exec
|
||||
filetype -p Tests:Conformance:TEST= src; change -p Tests:Conformance:TEST= exec
|
||||
filetype -p Tests:Deviance:=.CC src; change -p Tests:Deviance:=.CC cc
|
||||
filetype Tests:Deviance:D3401.DATA src; change Tests:Deviance:D3401.DATA cc
|
||||
filetype Tests:Deviance:DOIT src; change Tests:Deviance:DOIT exec
|
||||
filetype Tests:Deviance:RUN.DEVIANCE src; change Tests:Deviance:RUN.DEVIANCE exec
|
||||
filetype -p Tests:Deviance:TEST= src; change -p Tests:Deviance:TEST= exec
|
||||
filetype -p Tests:Spec.Conform:=.CC src; change -p Tests:Spec.Conform:=.CC cc
|
||||
filetype -p Tests:Spec.Conform:=.H src; change -p Tests:Spec.Conform:=.H cc
|
||||
filetype -p Tests:Spec.Conform:SPC3402= src; change -p Tests:Spec.Conform:SPC3402= cc
|
||||
filetype -p Tests:Spec.Conform:=FILE= src; change -p Tests:Spec.Conform:=FILE= cc
|
||||
filetype -p Tests:Spec.Conform:=.EXEC src; change -p Tests:Spec.Conform:=.EXEC exec
|
||||
filetype -p Tests:Spec.Deviance:=.CC src; change -p Tests:Spec.Deviance:=.CC cc
|
||||
filetype Tests:Spec.Deviance:DOIT src; change Tests:Spec.Deviance:DOIT exec
|
||||
filetype Tests:Spec.Deviance:TEST src; change Tests:Spec.Deviance:TEST exec
|
||||
|
||||
* Install udl and uncomment this to also convert to CR line endings.
|
||||
* udl -g =
|
||||
|
|
Loading…
Reference in New Issue