Commit 2adea773 authored by Neil Turton's avatar Neil Turton
Browse files

This commit was generated by cvs2git to track changes on a CVS vendor branch.

parents a257093a b4d69edf
| Copyright 1996 Acorn Computers Ltd
|
| Licensed under the Apache License, Version 2.0 (the "License");
| you may not use this file except in compliance with the License.
| You may obtain a copy of the License at
|
| http://www.apache.org/licenses/LICENSE-2.0
|
| Unless required by applicable law or agreed to in writing, software
| distributed under the License is distributed on an "AS IS" BASIS,
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
| See the License for the specific language governing permissions and
| limitations under the License.
|
Echo Making <Obey$Dir> ...
Prefix <Obey$Dir>
WIMPSlot -min 640K
WIMPSlot -max 640K
Do AMU -n -f <Obey$Dir>.Makefile -desktop
| Copyright 1996 Acorn Computers Ltd
|
| Licensed under the Apache License, Version 2.0 (the "License");
| you may not use this file except in compliance with the License.
| You may obtain a copy of the License at
|
| http://www.apache.org/licenses/LICENSE-2.0
|
| Unless required by applicable law or agreed to in writing, software
| distributed under the License is distributed on an "AS IS" BASIS,
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
| See the License for the specific language governing permissions and
| limitations under the License.
|
Echo Cleaning <Obey$Dir> ...
Prefix <Obey$Dir>
Do AMU -f <Obey$Dir>.Makefile -desktop clean
| Copyright 1996 Acorn Computers Ltd
|
| Licensed under the Apache License, Version 2.0 (the "License");
| you may not use this file except in compliance with the License.
| You may obtain a copy of the License at
|
| http://www.apache.org/licenses/LICENSE-2.0
|
| Unless required by applicable law or agreed to in writing, software
| distributed under the License is distributed on an "AS IS" BASIS,
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
| See the License for the specific language governing permissions and
| limitations under the License.
|
Echo Making <Obey$Dir> ...
Dir <Obey$Dir>
WIMPSlot -min 4000K
WIMPSlot -max 4000K
AMU -desktop
# Copyright 1996 Acorn Computers Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
CC = cc -IOS: -throwback -depend !Depend -wp
CHEADERS = h.advance h.ddeutils h.email h.hostfs h.nfs
HDRS = hdr.advance hdr.ddeutils hdr.email hdr.hostfs hdr.nfs
CSTRONG = Help.Advance Help.DDEUtils Help.EMail Help.HostFS Help.NFS
FILES = ${CHEADERS} ${HDRS} ${CSTRONG}
all: $(FILES)
cheaders: ${CHEADERS}
hdrs: ${HDRS}
cstrong: ${CSTRONG}
.SUFFIXES: .o .h .def .s .asm .c .Help .hdr
.def.h:
DefMod -h < $< > $@
.def.hdr:
DefMod -hdr < $< > $@
.def.Help:
CDir CStrong.$*
DefMod -cstrong -o CStrong.$* < $<
Create $@
#------------------------------------------------------------------------
# Dynamic dependencies:
Support version 0.11, as for RISC OS 3.60
a1 RN 0
a2 RN 1
a3 RN 2
a4 RN 3
v1 RN 4
v2 RN 5
ip RN 12
sp RN 13
lr RN 14
pc RN 15
AREA |C$$code|, CODE, READONLY
EXPORT muldiv
;;;; IMPORT raise
muldiv
; muldiv(a, b, c)
; result = a*b/c
; the intermediate product is 64 bits long
; do everything using moduluses, and sort out signs later
STMFD sp!, {a1, a2, a3, a4, v1, v2, lr}
; first, the double-length product, returned in a3 & a4
; uses ip, a1 and a2 as workspace
MOV a3, #0
MOV a4, #0
MOV ip, #0
CMPS a2, #0
RSBLT a2, a2, #0 ; abs b
MOV v2, a2
CMPS a1, #0
RSBLT a1, a1, #0 ; abs a
muldiv0
MOVS a2, a2, LSR #1
BCC muldiv1
ADDS a4, a4, a1
ADC a3, a3, ip
muldiv1
MOVS a1, a1, ASL #1
ADC ip, ip, ip
CMPS a2, #0
BNE muldiv0
; now the 64*32 bit divide
; dividend in a3 and a4
; remainder ends up in a4; quotient in ip
; uses a1 and a2 to hold the (shifted) divisor;
; v1 for the current bit in the quotient
LDR a2, [sp, #8] ; recover divisor
CMPS a2, #0
LDMEQFD sp!, {a1-a4, v1, v2, pc}^
;;was BEQ muldiv_by_0, but we might be a module
RSBLT a2, a2, #0 ; abs c
MOV v2, a2
MOV ip, #0
MOV a1, #0
MOV v1, #0
MOV lr, #1
muldiv2
CMPS a1, #&80000000
BCS muldiv3
CMPS a1, a3
CMPEQS a2, a4 ; compare of [a1, a2] against [a3, a4]
BCS muldiv3
MOVS a2, a2, ASL #1
MOV a1, a1, ASL #1
ADC a1, a1, #0
ADD v1, v1, #1
B muldiv2
muldiv3
CMPS a1, a3
CMPEQS a2, a4
BHI muldiv4
CMPS v1, #31
ADDLE ip, ip, lr, ASL v1
SUBS a4, a4, a2
SBC a3, a3, a1
muldiv4
MOVS a1, a1, ASR #1
MOV a2, a2, RRX
SUBS v1, v1, #1
BGE muldiv3
; now all we need to do is sort out the signs.
LDMFD sp!, {a1, a2, a3, v1}
EOR a2, a2, a1 ; a2 has the sign of a*b: a3 is the sign of c
MOV a1, ip
TEQS a2, a3 ; if a*b and c have opposite signs,
RSBMI a1, a1, #0 ; negate the quotient
CMPS a2, #0 ; and if the dividend was negative,
RSBLT a4, a4, #0 ; negate the remainder
;;;; Now discard the remainder - J R C 19 March 1991
;;;; STR a4, [v1]
LDMFD sp!, {v1, v2, pc}^
muldiv_by_0 ;not used
;;;; LDMFD sp!, {a1-a4, v1, v2, lr}
;;;; MOV a1, #2 ; SIGFPE
;;;; B raise
END
;svc.s - enter and leave SVC mode (ARM 3 specific)
;written by Jonathan Coxhead, 1st Feb 1994
R0 RN 0
R1 RN 1
R2 RN 2
R3 RN 3
R4 RN 4
R5 RN 5
R6 RN 6
R7 RN 7
R8 RN 8
R9 RN 9
A1 RN 0
A2 RN 1
A3 RN 2
A4 RN 3
V1 RN 4
V2 RN 5
V3 RN 6
V4 RN 7
V5 RN 8
V6 RN 9
R RN 0
SL RN 10
FP RN 11
IP RN 12
SP RN 13
LR RN 14
PC RN 15
EXPORT svc_enter
EXPORT svc_exit
AREA |C$$code|, CODE, READONLY
svc_enter ROUT
MOV R1, LR
SWI &16
MOV PC, R1
svc_exit ROUT
BICS PC, LR, #3
END
/* Copyright 1996 Acorn Computers Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*application.c - useful functions for windowing applications*/
/*From CLib*/
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*From OSLib*/
#include "os.h"
#include "wimp.h"
#include "wimpreadsysinfo.h"
/*From Support*/
#include "application.h"
#include "task.h"
#include "trace.h"
bool application_polling_idle; /*set if Wimp_PollIdle is required*/
int application_timeout; /*WIMP timeout, to be passed to Wimp_PollIdle*/
bool application_quit; /*flag to be set when application() is to return*/
int *application_pollword; /*address to be set to a pollword, if required*/
callback_l application_list;
task_r application_task;
static wimp_block Block;
/*------------------------------------------------------------------------*/
os_error *application_initialise (char *programme,
wimp_message_list *messages)
/*Call Wimp_Initialise and create the block for |application_task|.*/
{ os_error *error = NULL, *e;
int version;
wimp_t task;
bool done_initialise = FALSE, done_new = FALSE;
tracef ("application_initialise\n");
/*Required to start up as a new task.*/
if ((e = xwimpreadsysinfo_version (&version)) != NULL)
{ if (e->errnum == error_WIMP_BAD_SYS_INFO)
version = wimp_VERSION_RO2;
else
{ error = e;
goto finish;
} }
tracef ("Wimp version %d\n" _ version);
if (version >= wimp_VERSION_RO35)
version = wimp_VERSION_RO35;
else if (version >= wimp_VERSION_RO3)
version = wimp_VERSION_RO3;
else if (version >= wimp_VERSION_RO30)
version = wimp_VERSION_RO30;
if ((error = xwimp_initialise (version, programme, messages,
NULL, &task)) != NULL)
goto finish;
done_initialise = TRUE;
if ((error = task_new (programme, task, &application_task)) != NULL)
goto finish;
done_new = TRUE;
application_list = task_list (application_task);
finish:
if (error != NULL)
{ if (done_new)
task_delete (application_task);
if (done_initialise)
{ os_error *error1 = xwimp_close_down (0);
if (error == NULL) error = error1;
} }
if (error != NULL)
tracef ("ERROR: %s (error 0x%X)\n" _ error->errmess _ error->errnum);
return error;
}
/*------------------------------------------------------------------------*/
os_error *application_terminate (void)
/* Call Wimp_CloseDown and delete |application_task|.*/
{ os_error *error = NULL, *error1;
tracef ("application_terminate\n");
error1 = xwimp_close_down ((wimp_t) 0);
if (error == NULL) error = error1;
error1 = task_delete (application_task);
if (error == NULL) error = error1;
/*finish:*/
if (error != NULL)
tracef ("ERROR: %s (error 0x%X)\n" _ error->errmess _ error->errnum);
return error;
}
/*------------------------------------------------------------------------*/
void application (void)
/*Sits in a loop, processing |application_task|. Error processing note:
wimp_{poll,poll_idle} report any error they see (rather than returning
it), with the exception of argument checking errors: so it is
appropriate to abort the loop and report the error if this happens. The
callbacks made can also return their own error, and we just report
these unless in a redraw event.*/
{ int event;
os_error *error = NULL, *error1;
tracef ("application\n");
do
{ if (!application_polling_idle)
{ if ((error = xwimp_poll (task_mask (application_task), &Block,
application_pollword, &event)) != NULL)
goto finish;
}
else
{ if ((error = xwimp_poll_idle (task_mask (application_task), &Block,
application_timeout, application_pollword, &event)) != NULL)
goto finish;
}
error1 = task_callback (application_task, NULL, event, &Block, NULL);
if (event != wimp_REDRAW_WINDOW_REQUEST)
task_report_error (application_task, error1);
}
while (!application_quit);
finish:
task_report_error (application_task, error);
}
/*------------------------------------------------------------------------*/
bits application_claim (int event)
{ tracef ("application_claim\n");
return task_claim (application_task, event);
}
/*------------------------------------------------------------------------*/
bits application_release (int event)
{ tracef ("application_release\n");
return task_release (application_task, event);
}
/*------------------------------------------------------------------------*/
os_error *application_report_error (os_error *error)
{ tracef ("application_report_error\n");
return task_report_error (application_task, error);
}
/* Copyright 1996 Acorn Computers Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*bezierarc.c - construct bezier curves from arcs*/
/* Author: David Elworthy
Version: 0.10
History: 0.00 - 18 July 1988 - created
0.10 - 19 July 1988
12 June 1989 - header added
0.20 - 4th Oct 1993 Changed to use OSLib (os_coord). J R C
Based on ideas by David Seal. Ask him about the hard bits.
The 'maximum angle' is the longest chunk we want implemented as a single
path element. This is assumed to be 90 degrees.
All coordinates, radii and centres are passed in draw units, generally
as coordinate structures. All angles are passed in radians, in double
format. Internal computation is done in doubles.
Note that arcs which have start and end angles very close together will
appear as circles. This only happens when the difference in angles is
less than about 1e-12 degrees.
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "os.h"
#include "bezierarc.h"
/*Useful constants for 90 degree arcs*/
#define K90 0.552284750 /*4*(sqrt 2 - 1)/3*/
#define COS45 0.707106781 /*1/sqrt 2*/
/*
Function : bezierarc_short
Purpose : calculate bezier points for an arc of less than 90 degrees
Parameters : centre of arc
start angle
end angle
radius
OUT: start point
end point
bezier control point 1
bezier control point 2
Returns : void
Description : the bezier control points are calculated as follows:
1. Conceptually centre the arc on 0,0; the end points are defined to
be (X1, Y1), (X2, Y2) in this coordinate system. X1, X2, Y1, Y2 can be
calculated from the parameters.
2. The control points are then (X1 - k.Y1, Y1 + k.X1) and
(X2 + k.Y2, Y2 - k.X2) where k is a positive constant obtained from:
k = 4 (SQR (2. (X1^2 + Y1^2). (X1^2 + Y1^2 + X1.X2 + Y1.Y2))
- (X1^2 + Y1^2 + X1.X2 + Y1.Y2)) / 3 (X1.Y2 - Y1.X2)
3. Having obtained these control points, shift back to the true origin.
(x1, y1) and (x2, y2) are returned as the start and end points
Note that there is no check that the angle is less than the maximum.
*/
void bezierarc_short (os_coord centre, double start_angle, double end_angle,
int radius, os_coord *start, os_coord *end, os_coord *control1,
os_coord *control2)
{ double x1, y1, x2, y2, k, x1sq_plus_y1sq, sq_plus_x1x2_plus_y1y2;
/*Calculate end points, based on (0,0)*/
x1 = radius*cos (start_angle);
y1 = radius*sin (start_angle);
x2 = radius*cos (end_angle);
y2 = radius*sin (end_angle);
/*Record start and end locations*/
start->x = centre.x + (int) x1;
start->y = centre.y + (int) y1;
end->x = centre.x + (int) x2;
end->y = centre.y + (int) y2;
/*Calculate k*/
x1sq_plus_y1sq = x1*x1 + y1*y1;
sq_plus_x1x2_plus_y1y2 = x1sq_plus_y1sq + x1*x2 + y1*y2;
k = 4*(sqrt (2*x1sq_plus_y1sq*sq_plus_x1x2_plus_y1y2) -
sq_plus_x1x2_plus_y1y2)/(3*(x1*y2 - y1*x2));
/*Find control points, including origin shift*/
control1->x = (int) (centre.x + x1 - k*y1);
control1->y = (int) (centre.y + y1 + k*x1);
control2->x = (int) (centre.x + x2 + k*y2);
control2->y = (int) (centre.y + y2 - k*x2);
}
/*
Function : bezierarc_90
Purpose : find bezier control points for 90 degree arc
Parameters : centre of arc
start angle of arc
radius
OUT: start point
end point
bezier control point 1
bezier control point 2
Returns : void
Description : the control points are calculated as follows:
1. Conceptually shift the centre to (0, 0). The arc then runs from (X, Y)
to (Y, -X), which can be found from the radius and start angle.
2. Calculate the bezier control points as (X-kY, Y+kX) and (kX-Y, kY+X)
where k = 4 (SQR (2)-1)/3 [precalculated]
3. Shift the control points to allow for the actual centre.
The shifted versions of (X, Y) and (Y, -X) are returned as the start
and end points.
Note: when the arc is already axis aligned and centred on (0,0), use
Axis_Aligned instead.
*/
void bezierarc_90 (os_coord centre, double start_angle, int radius,
os_coord *start, os_coord *end, os_coord *control1,
os_coord *control2)
{ double x, y, kx, ky;
/*Calculate X and Y, and multiples needed for Bezier*/
x = radius*cos (start_angle);
y = radius*sin (start_angle);
kx = K90*x;
ky = K90*y;
/*Find control points and end points, applying origin shift*/
start->x = centre.x + (int) x;
start->y = centre.y + (int) y;
end->x = centre.x + (int) -y;
end->y = centre.y + (int) x;
control1->x = (int) (centre.x + x - ky);
control1->y = (int) (centre.y + y + kx);
control2->x = (int) (centre.x + kx - y);
control2->y = (int) (centre.y + ky + x);
}
/*
Function : Axis_Aligned
Purpose : draw a centred 90 degress arc, axis aligned
Parameters : radius
OUT: start point
end point
bezier control point 1
bezier control point 2
Returns : void
Description : this is used to draw a 90 degree arc, centred on the positive
y axis, with the arc centre at (0,0). Its main use is in
drawing circles. The method is essentially that of
bezierarc_90, but with some calculations taken out. The start
angle is taken as 45 degrees, so it has a cos of 1/SQR (2)
and a sine of 1/SQR (2).
The start and end points are then (x,y) and (-x,y) [x=y].
Since x = y (and hence kx = ky), the control points simplify
to (x-kx, x+kx) and (kx-x), (kx+x)
*/
static void Axis_Aligned (int radius, os_coord *start, os_coord *end,
os_coord *control1, os_coord *control2)
{ double x, kx;
int ix;