home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 44
/
Amiga_Dream_44.iso
/
RiscPc
/
programmation
/
scm4e2.arc
/
!Scm
/
c
/
archi
Wrap
Text File
|
1995-08-03
|
13KB
|
640 lines
/*
| Acorn Archimedes Extensions for GNU Scheme Interpreter
| This code is subject to the GPL - see below...
| (C) Al Slater 1994->
| ams@csd.abdn.ac.uk
*/
#include "scm.h" /* includes scmfig.h as well */
#include "patchlvl.h" /* Guess... */
#include <math.h> /* for turtle stuff */
#include <sys/os.h> /* archi os stuff */
/* --- internal OS definitions */
#define OS_WriteC 0x0
#define OS_ReadC 0x4
#define OS_RemoveCursors 0x36
#define OS_RestoreCursors 0x37
#define OS_Plot 0x45
/* --- globals for turtling --- */
#define TDN 360
#ifndef PI
# undef PI
# define PI 3.141592654
#endif /* PI */
static float CO[TDN];
static float SI[TDN];
float TurtleX,TurtleY; /* where are we on screen? */
int TurtleDir; /* direction as int */
int penup; /* pen up or down? */
int o_heading,home_x,home_y;
/* names of functions */
static char s_arc_cls[] = "cls";
static char s_arc_clg[] = "clg";
static char s_arc_circle[] = "circle";
static char s_arc_draw[] = "draw";
static char s_arc_fill[] = "fill";
static char s_arc_gcol[] = "gcol";
static char s_arc_get[] = "get";
static char s_arc_graphics_origin[] = "graphics-origin!";
static char s_arc_mode[] = "mode";
static char s_arc_move[] = "move";
static char s_arc_plot[] = "plot";
static char s_arc_point[] = "point";
static char s_arc_remove_cursor[] = "remove-cursor!";
static char s_arc_restore_cursor[] = "restore-cursor!";
static char s_arc_text_colour[] = "text-colour!";
static char s_arc_text_cursor[] = "text-cursor!";
static char s_arc_vdu[] = "vdu";
static char s_arc_vdu25[] = "vdu25";
static char s_arc_vdu29[] = "vdu29";
static char s_arc_wait[] = "wait";
static char s_arc_wrc2[] = "_wrc2";
static char s_arc_swi[] = "swi";
/* --- turtle routines */
static char s_arc_forward[] = "forward";
static char s_arc_init_turtle[] = "init-turtle";
static char s_arc_turn[] = "turn";
static char s_arc_pen_up[] = "pen-up";
static char s_arc_pen_down[] = "pen-down";
static char s_arc_pen_upp[] = "pen-up?";
static char s_arc_pen_downp[] = "pen-down?";
static char s_arc_home[] = "home";
/*
| Code for actual scheme functions starts here
*/
/* perform OS_WriteC */
void os_wrc(x)
int x;
{
int reg[10];
reg[0] = x;
os_swi(OS_WriteC,reg);
}
/* change the video mode to whatever */
SCM arc_mode(n)
SCM n;
{
int m;
ASSERT( INUMP(n),n,ARG1,s_arc_mode ); /* integers only */
m = INUM(n);
os_wrc(22);
os_wrc(m);
return MAKINUM( m );
}
/* generic plot command */
SCM arc_vdu25(type,x,y)
SCM type,x,y;
{
int atype;
unsigned ax,ay;
ASSERT( INUMP(type),type,ARG1,s_arc_vdu25 );
ASSERT( INUMP(x),x,ARG2,s_arc_vdu25 );
ASSERT( INUMP(y),y,ARG3,s_arc_vdu25 );
atype = INUM(type);
ax = INUM(x); ay = INUM(y);
os_wrc(25); /* vdu 25 == plot */
os_wrc(atype);
os_wrc(ax);
ax >>= 8;
os_wrc(ax);
os_wrc(ay);
ay >>= 8;
os_wrc(ay);
return MAKINUM(atype);
}
SCM arc_vdu29(x,y)
SCM x,y;
{
int byte;
unsigned ax,ay;
ASSERT( INUMP(x),x,ARG1,s_arc_vdu29 );
ASSERT( INUMP(y),y,ARG2,s_arc_vdu29 );
ax = INUM(x); ay = INUM(y);
os_wrc(29);
byte = ax;
os_wrc(byte);
byte >>= 8;
os_wrc(byte);
byte = ay;
os_wrc(byte);
byte >>= 8;
os_wrc(byte);
return UNSPECIFIED;
}
SCM arc_wrc2(x)
SCM x;
{
int byte;
ASSERT ( INUMP(x), x, ARG1, s_arc_wrc2 );
byte = INUM(x);
os_wrc(byte);
byte >>= 8;
os_wrc(byte);
return UNSPECIFIED;
}
SCM arc_text_cursor(x,y)
SCM x,y;
{
int ax,ay;
ASSERT( INUMP(x),x,ARG1,s_arc_vdu29 );
ASSERT( INUMP(y),y,ARG2,s_arc_vdu29 );
ax = INUM(x); ay = INUM(y);
os_wrc(31); /* position text cursor */
os_wrc(ax); /* x */
os_wrc(ay); /* y */
return UNSPECIFIED;
}
SCM arc_text_colour(i)
SCM i;
{
int ai;
ASSERT( INUMP(i),i,ARG1,s_arc_text_colour );
ai = INUM (i);
os_wrc(17); /* vdu 17,... == change current text colour */
os_wrc(ai);
return MAKINUM( ai );
}
SCM arc_remove_cursor()
{
int reg[10];
os_swi(OS_RemoveCursors,reg);
return UNSPECIFIED;
}
SCM arc_restore_cursor()
{
int reg[10];
os_swi(OS_RestoreCursors,reg);
return UNSPECIFIED;
}
SCM arc_plot(p,x,y)
SCM p,x,y;
{
int reg[10];
ASSERT( INUMP(p),p,ARG1,s_arc_plot );
ASSERT( INUMP(x),x,ARG2,s_arc_plot );
ASSERT( INUMP(y),y,ARG3,s_arc_plot );
reg[0] = INUM(p); /* plot code */
reg[1] = INUM(x); /* x coord */
reg[2] = INUM(y); /* y coord */
os_swi(OS_Plot,reg);
return UNSPECIFIED;
}
SCM arc_move(x,y)
SCM x,y;
{
int ax,ay,reg[10];
ASSERT( INUMP(x),x,ARG1,s_arc_move );
ASSERT( INUMP(y),y,ARG2,s_arc_move );
ax = INUM(x); ay = INUM(y);
reg[0] = 4; /* PLOT code for a move */
reg[1] = ax; /* x coord */
reg[2] = ay; /* y coord */
os_swi(OS_Plot,reg);
return UNSPECIFIED;
}
SCM arc_circle(x,y,rad)
SCM x,y,rad;
{
int ax,ay,arad,reg[10];
ASSERT( INUMP(x),x,ARG1,s_arc_circle );
ASSERT( INUMP(y),y,ARG2,s_arc_circle );
ASSERT( INUMP(rad),rad,ARG3,s_arc_circle);
ax = INUM( x );
ay = INUM( y );
arad = INUM( rad );
reg[0] = 4; /* PLOT code for a move */
reg[1] = ax; /* x coord */
reg[2] = ay; /* y coord */
os_swi(OS_Plot,reg);
reg[0] = 145;
reg[1] = arad;
reg[2] = 0;
os_swi(OS_Plot,reg);
return UNSPECIFIED;
}
SCM arc_wait()
{
int reg[10];
reg[0] = 19;
os_swi(0x6,reg);
return UNSPECIFIED;
}
SCM arc_gcol(a,c)
SCM a,c;
{
int aa,ac;
ASSERT( INUMP(a),a,ARG1,s_arc_gcol );
ASSERT( INUMP(c),c,ARG2,s_arc_gcol );
aa = INUM(a);
ac = INUM(c);
os_wrc(18); /* gcol == vdu 18,..,.. */
os_wrc(aa); /* action code */
os_wrc(ac); /* colour */
return UNSPECIFIED;
}
SCM arc_cls()
{
os_wrc(12); /* clear screen */
return UNSPECIFIED;
}
SCM arc_clg()
{
os_wrc(16); /* clear gfx screen */
return UNSPECIFIED;
}
SCM arc_fill(x,y)
SCM x,y;
{
int ix,iy,reg[10];
ASSERT( INUMP(x),x,ARG1,s_arc_fill );
ASSERT( INUMP(y),y,ARG2,s_arc_fill );
ix = INUM(x);
iy = INUM(y);
reg[0] = 133;
reg[1] = ix;
reg[2] = iy;
os_swi(OS_Plot,reg);
return UNSPECIFIED;
}
SCM arc_point(x,y)
SCM x,y;
{
int ix,iy,reg[10];
ASSERT ( INUMP(x), x, ARG1, s_arc_point );
ASSERT ( INUMP(y), y, ARG2, s_arc_point );
ix = INUM(x);
iy = INUM(y);
reg[0] = 69; /* plot code for point */
reg[1] = ix;
reg[2] = iy;
os_swi(OS_Plot,reg);
return MAKINUM( reg[0] );
}
SCM arc_draw(x,y)
SCM x,y;
{
int reg[10],ix,iy;
ASSERT ( INUMP(x), x, ARG1, s_arc_draw );
ASSERT ( INUMP(y), y, ARG2, s_arc_draw );
ix = INUM(x);
iy = INUM(y);
reg[0] = 5;
reg[1] = ix;
reg[2] = iy;
os_swi(OS_Plot,reg);
return UNSPECIFIED;
}
/* straight interface onto vdu driver */
SCM arc_vdu(n)
SCM n;
{
int in;
ASSERT( INUMP(n), n, ARG1, s_arc_vdu );
in = INUM(n);
os_wrc(in);
return MAKINUM ( in );
}
SCM arc_get()
{
int reg[10];
os_swi(OS_ReadC,reg);
return MAKINUM( reg[0] );
}
/* --- end of C code for extensions */
/* --- code for turtling start here --- */
SCM arc_forward(n)
SCM n;
{
int in,reg[10];
ASSERT( INUMP(n), n, ARG1, s_arc_forward );
in = INUM(n);
TurtleX += (in*CO[TurtleDir]);
TurtleY += (in*SI[TurtleDir]);
reg[0] = penup ? 4 : 5;
reg[1] = floor(TurtleX);
reg[2] = floor(TurtleY);
os_swi(OS_Plot,reg);
return UNSPECIFIED;
}
SCM arc_init_turtle(x,y,h)
SCM x,y,h;
{
int reg[10];
ASSERT( INUMP(x), x, ARG1, s_arc_init_turtle );
ASSERT( INUMP(y), y, ARG2, s_arc_init_turtle );
ASSERT( INUMP(h), h, ARG3, s_arc_init_turtle );
home_x = INUM(x); home_y = INUM(y);
o_heading = INUM(h);
if (o_heading < 0) o_heading = 0;
if (o_heading > 360) o_heading = 0;
TurtleX = (float)home_x;
TurtleY = (float)home_y;
TurtleDir = o_heading;
/* now move to where we initted the graphics pen to.. */
reg[0] = 4;
reg[1] = home_x;
reg[2] = home_y;
os_swi(OS_Plot,reg);
return UNSPECIFIED;
}
SCM arc_turn(n)
SCM n;
{
int in;
ASSERT ( INUMP(n), n, ARG1, s_arc_turn );
in = INUM(n);
/* add on if we can turn... */
TurtleDir += (in % TDN);
/* oops! too far! - make it sensible... */
if (TurtleDir >= TDN) TurtleDir = (TurtleDir % TDN);
else if (TurtleDir < 0) TurtleDir = (TDN+TurtleDir) % TDN;
return MAKINUM(TurtleDir); /* where we are currently pointing */
}
SCM arc_pen_up() { penup = 1; return UNSPECIFIED; }
SCM arc_pen_down() { penup = 0; return UNSPECIFIED; }
SCM arc_pen_upp() {
if (penup == 1)
return(BOOL_T) ;
else
return(BOOL_F);
}
SCM arc_pen_downp() {
if (penup == 0)
return (BOOL_T);
else
return (BOOL_F);
}
SCM arc_home() {
int reg[10];
reg[0] = 4;
reg[1] = home_x;
reg[2] = home_y;
os_swi(OS_Plot,reg);
TurtleX = home_x;
TurtleY = home_y;
TurtleDir = o_heading;
return UNSPECIFIED;
}
SCM arc_swi(number,regs)
SCM number;
SCM regs;
{
int swiN,no_regs = 0,at = 0;
int swiregs[10];
SCM itr = regs;
SCM res = EOL;
ASSERT(INUMP(number), number, ARG1, s_arc_swi);
ASSERT(CONSP(regs), regs, ARG2, s_arc_swi);
swiN = INUM(number);
if ((no_regs = ilength(regs)) < 0 || NULLP(regs) || no_regs>10) {
wta(regs,(char *)ARG2,s_arc_swi);
}
do {
if (INUMP(CAR(itr))) {
swiregs[at++] = INUM(CAR(itr));
continue;
} else if (NIMP(CAR(itr)) && STRINGP(CAR(itr))) {
swiregs[at++] = (int)CHARS(CAR(itr));
continue;
}
} while ((itr = CDR(itr)) != EOL);
/* zero remaining, for return tidyness... */
for(;at<10;at++) swiregs[at] = 0;
os_swi(swiN,swiregs);
for(--at;at>=0;at--) res = cons(MAKINUM(swiregs[at]),res);
return res;
}
SCM arc_dehex(str) /* god I'm a lazy bastard >:-) */
SCM str;
{
char *scanstr;
int res;
ASSERT( NIMP(str) && STRINGP(str), str, ARG1, "_dehex");
scanstr = CHARS(str);
if (*scanstr == '\0') wta(str,(char *)ARG1,"_dehex");
sscanf(scanstr,"%x",&res);
return MAKINUM(res);
}
SCM arc_dsptr(addr)
SCM addr;
{
char *ptr;
/* this ia APPALLING abuse!... */
ASSERT( INUMP(addr), addr, ARG1, "_dsptr");
ptr = (char *)INUM(addr);
return makfromstr(ptr,strlen(ptr));
}
/*
SCM arc_intp(str)
SCM str;
{
char *ptr;
char *n;
ASSERT(NIMP(str) && STRINGP(str), str, ARG1, "_intp");
ptr = CHARS(str);
n = (char *)malloc(strlen(ptr)+1);
strcpy(n,ptr);
return MAKINUM((int)n);
}
*/
SCM arc_free(ptr)
SCM ptr;
{
void *aptr;
ASSERT(INUMP(ptr), ptr, ARG1, "_free");
aptr = (void *)INUM(ptr);
free(aptr);
return UNSPECIFIED;
}
SCM arc_makebuf(sz)
SCM sz;
{
int size;
char *buffer;
ASSERT(INUMP(sz), sz, ARG1, "_makebuf");
size=INUM(sz);
buffer = (char *)malloc(size+1);
memset(buffer,' ',size);
buffer[size] = '\0';
return MAKINUM((int)buffer);
}
/* bind names to functions */
static iproc archi0[] = {
{ s_arc_remove_cursor, arc_remove_cursor },
{ s_arc_restore_cursor, arc_restore_cursor },
{ s_arc_wait, arc_wait },
{ s_arc_cls, arc_cls },
{ s_arc_clg, arc_clg },
{ s_arc_get, arc_get },
{ s_arc_pen_up, arc_pen_up },
{ s_arc_pen_down, arc_pen_down },
{ s_arc_pen_upp, arc_pen_upp },
{ s_arc_pen_downp, arc_pen_downp },
{ s_arc_home, arc_home },
{ 0,0 }
};
static iproc archi1[] = {
{ s_arc_mode, arc_mode },
{ s_arc_text_colour, arc_text_colour },
{ s_arc_vdu, arc_vdu },
{ s_arc_wrc2, arc_wrc2 },
{ s_arc_forward, arc_forward },
{ s_arc_turn, arc_turn },
{ "_dehex", arc_dehex },
{ "_dsptr", arc_dsptr },
/* { "_intp", arc_intp }, */
{ "_free", arc_free },
{ "_makebuf", arc_makebuf },
{ 0,0 }
};
static iproc archi2[] = {
{ s_arc_vdu29, arc_vdu29 },
{ s_arc_graphics_origin, arc_vdu29 },
{ s_arc_text_cursor, arc_text_cursor },
{ s_arc_move, arc_move },
{ s_arc_gcol, arc_gcol },
{ s_arc_fill, arc_fill },
{ s_arc_point, arc_point },
{ s_arc_draw, arc_draw },
{ s_arc_swi, arc_swi },
{ 0,0 }
};
static iproc archi3[] = {
{ s_arc_vdu25, arc_vdu25 },
{ s_arc_plot, arc_plot },
{ s_arc_circle, arc_circle },
{ s_arc_init_turtle, arc_init_turtle },
{ 0,0 }
};
void init_arcext()
{
int i;
init_iprocs( archi0, tc7_subr_0 );
init_iprocs( archi1, tc7_subr_1 );
init_iprocs( archi2, tc7_subr_2 );
init_iprocs( archi3, tc7_subr_3 );
puts( "\nSCM Acorn Archimedes Extensions (C) 1994 ams@csd.abdn.ac.uk\n" );
/* ok now setup turtle stuff.. */
for (i=0; i<TDN; i++) {
CO[i] = cos(2*PI*i/TDN);
SI[i] = sin(2*PI*i/TDN);
}
/* pen starts down */
penup = 0;
o_heading = home_x = home_y = 0;
} /* init_archi() */