home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-387-Vol-3of3.iso
/
x
/
xvisrc.zoo
/
tos.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-28
|
8KB
|
438 lines
/* Copyright (c) 1990,1991,1992 Chris and John Downey */
#ifndef lint
static char *sccsid = "@(#)tos.c 2.1 (Chris & John Downey) 7/29/92";
#endif
/***
* program name:
xvi
* function:
Portable version of UNIX "vi" editor, with extensions.
* module name:
tos.c
* module function:
System interface module for the Atari ST.
* history:
STEVIE - ST Editor for VI Enthusiasts, Version 3.10
Originally by Tim Thompson (twitch!tjt)
Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
Heavily modified by Chris & John Downey
Atari port modified by Steve Found for LATTICE C V5.0
***/
#include "xvi.h"
#include <osbind.h>
/*
* The following buffer is used to work around a bug in TOS. It appears that
* unread console input can cause a crash, but only if console output is
* going on. The solution is to always grab any unread input before putting
* out a character. The following buffer holds any characters read in this
* fashion. The problem can be easily produced because we can't yet keep
* up with the normal auto-repeat rate in insert mode.
*/
#define IBUFSZ 128
static long inbuf[IBUFSZ]; /* buffer for unread input */
static long *inptr = inbuf; /* where to put next character */
/*
* These are globals which are set by the OS-specific module,
* and used for various purposes throughout the rest of xvi.
*/
int Rows; /* Number of Rows and Columns */
int Columns; /* in the current window. */
static char tmpbuff[L_tmpnam];
static char *logscreen;
/*
* inchar() - get a character from the keyboard
*
* Certain special keys are mapped to values above 0x80. These
* mappings are defined in keymap.h. If the key has a non-zero
* ascii value, it is simply returned. Otherwise it may be a
* special key we want to map.
*
* The ST has a bug involving keyboard input that seems to occur
* when typing quickly, especially typing capital letters. Sometimes
* a value of 0x02540000 is read. This doesn't correspond to anything
* on the keyboard, according to my documentation. My solution is to
* loop when any unknown key is seen. Normally, the bell is rung to
* indicate the error. If the "bug" value is seen, we ignore it completely.
*
* "timeout" parameter not handled at the moment.
*/
int
inchar(timeout)
long timeout;
{
int k, s;
for (;;) {
long c;
/*
* Get the next input character, either from the input
* buffer or directly from TOS.
*/
if (inptr != inbuf) { /* input in the buffer, use it */
long *p;
c = inbuf[0];
/*
* Shift everything else in the buffer down. This
* would be cleaner if we used a circular buffer,
* but it really isn't worth it.
*/
inptr--;
for (p = inbuf; p < inptr ;p++)
*p = *(p+1);
} else {
c = Crawcin();
}
k = (c & 0xFF);
s = (c >> 16) & 0xFF;
if (k != 0)
break;
switch (s) {
case 0x62: k = K_HELP; break;
case 0x61: k = K_UNDO; break;
case 0x52: k = K_INSERT; break;
case 0x47: k = K_HOME; break;
case 0x48: k = K_UARROW; break;
case 0x50: k = K_DARROW; break;
case 0x4b: k = K_LARROW; break;
case 0x4d: k = K_RARROW; break;
case 0x29: k = K_CGRAVE; break; /* control grave accent */
/*
* Occurs due to a bug in TOS.
*/
case 0x54:
break;
/*
* Add the function keys here later if we put in support
* for macros.
*/
default:
k = 0;
alert();
break;
}
if (k != 0) {
break;
}
}
return(k);
}
/*
* get_inchars - snarf away any pending console input
*
* If the buffer overflows, we discard what's left and ring the bell.
*/
static void
get_inchars()
{
while (Cconis()) {
if (inptr >= &inbuf[IBUFSZ]) { /* no room in buffer? */
Crawcin(); /* discard the input */
alert(); /* and sound the alarm */
} else {
*inptr++ = Crawcin();
}
}
}
void
outchar(c)
char c;
{
get_inchars();
Cconout((short)c);
}
void
outstr(s)
register char *s;
{
get_inchars();
Cconws(s);
}
#define BGND 0
#define TEXT 1
/*
* vbeep() - visual bell
*/
static void
vbeep()
{
int text, bgnd; /* text and background colors */
long l;
text = Setcolor(TEXT, -1);
bgnd = Setcolor(BGND, -1);
Setcolor(TEXT, (short) bgnd); /* swap colors */
Setcolor(BGND, (short) text);
for (l=0; l < 5000 ;l++) /* short pause */
;
Setcolor(TEXT, (short) text); /* restore colors */
Setcolor(BGND, (short) bgnd);
}
void
alert()
{
if (Pb(P_vbell))
vbeep();
else
outchar('\007');
}
bool_t
can_write(file)
char *file;
{
if (access(file, 0) == -1 || access(file, 2) == 0) {
return(TRUE);
} else {
return(FALSE);
}
}
/*
* remove(file) - remove a file
* I don't know whether success is detectable here - cmd.
*/
#ifndef LATTICE
bool_t
remove(file)
char *file;
{
Fdelete(file);
return(TRUE);
}
#endif
void
sys_init()
{
logscreen = (char *) Logbase();
if (Getrez() == 0)
Columns = 40; /* low resolution */
else
Columns = 80; /* medium or high */
Rows = 25;
Cursconf(1, NULL);
}
void
sys_startv()
{
}
void
sys_endv()
{
}
void
sys_exit(r)
int r;
{
tty_goto(25, 0);
outchar('\n');
exit(r);
}
void
tty_goto(r, c)
int r, c;
{
outstr("\033Y");
outchar(r + ' ');
outchar(c + ' ');
}
/*
* System calls or library routines missing in TOS.
*/
void
sleep(n)
unsigned n;
{
int k;
k = Tgettime();
while (Tgettime() <= k + n)
;
}
void
delay()
{
long n;
for (n = 0; n < 8000; n++)
;
}
#ifndef LATTICE
int
system(cmd)
char *cmd;
{
char arg[1];
arg[0] = '\0'; /* no arguments passed to the shell */
if (Pexec(0, cmd, arg, 0L) < 0) {
return(-1);
} else {
return(0);
}
}
#endif
#ifdef MEGAMAX
char *
strchr(s, c)
char *s;
int c;
{
do {
if (*s == c)
return(s);
} while (*s++);
return(NULL);
}
#endif /* MEGAMAX */
/*
* getenv() - get a string from the environment
*
* Both Alcyon and Megamax are missing getenv(). This routine works for
* both compilers and with the Beckemeyer and Gulam shells. With gulam,
* the env_style variable should be set to either "mw" or "gu".
*/
#ifndef LATTICE
char *
getenv(name)
char *name;
{
extern long _base;
char *envp, *p;
envp = *((char **) (_base + 0x2c));
for ( ; *envp; envp += strlen(envp) + 1) {
if (strncmp(envp, name, strlen(name)) == 0) {
p = envp + strlen(name);
if (*p++ == '=')
return(p);
}
}
return(NULL);
}
#endif
/*
* Set the specified colour. Just does standout/standend mode for now.
* Optimisation here to avoid setting standend when we aren't in
* standout; assumes calling routines are well-behaved (i.e. only do
* screen movement in P_colour) or some terminals will write garbage
* all over the screen.
*/
void
set_colour(c)
int c;
{
static int oldc = -1;
if (c == oldc)
return;
if (c != 0)
outstr("\033p");
else
outstr("\033q");
oldc = c;
}
/*
* tempfname - Create a temporary file name.
*/
char *
tempfname(srcname)
char *srcname;
{
return(tmpnam(tmpbuff));
}
#ifndef ABS
# define ABS(n) ((n) < 0 ? -(n) : (n))
#endif
/*
* Scroll the ST Monochrome screen.
*/
void
st_scroll(start, end, nlines)
unsigned start, end;
int nlines;
{
char *s, *e, *d;
char *s2;
size_t bytes, clr_bytes;
if (ABS(nlines) > (end + 1 - start) || nlines == 0)
return;
invis_cursor();
if (nlines > 0) {
d = logscreen + (start * 1280);
s = d + (nlines * 1280);
s2 = d + bytes;
} else /* (nlines < 0) */ {
nlines = -nlines;
s2 = s = logscreen + (start * 1280);
d = s + (nlines * 1280);
}
/*
* Move the appropriate lines up or down.
*/
bytes = (end + 1 - start - nlines) * 1280;
memmove(d, s, bytes);
/*
* Clear the ones left behind.
*/
clr_bytes = ((end + 1 - start) * 1280) - bytes;
(void) memset(s2, 0, clr_bytes);
vis_cursor();
}