home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-02-03 | 58.3 KB | 2,433 lines |
- Path: xanth!mcnc!ncsuvx!lll-winken!lll-tis!ames!necntc!ncoast!allbery
- From: BLARSON@ECLA.USC.EDU (Bob Larson)
- Newsgroups: comp.sources.misc
- Subject: v03i036: mg 2a part 12 of 15
- Message-ID: <12401301117.47.BLARSON@ECLA.USC.EDU>
- Date: 26 May 88 05:01:37 GMT
- Sender: allbery@ncoast.UUCP
- Reply-To: BLARSON@ECLA.USC.EDU (Bob Larson)
- Lines: 2420
- Approved: allbery@ncoast.UUCP
-
- comp.sources.misc: Volume 3, Issue 36
- Submitted-By: "Bob Larson" <BLARSON@ECLA.USC.EDU>
- Archive-Name: mg2a/Part12
-
- # This is a shell archive.
- # Remove everything above and including the cut line.
- # Then run the rest of the file through sh.
- #----cut here-----cut here-----cut here-----cut here----#
- #!/bin/sh
- # shar: Shell Archiver
- # Run the following text with /bin/sh to create:
- # sys/atari/readme.1st
- # sys/atari/alloc.c
- # sys/atari/build.g
- # sys/atari/cinfo.c
- # sys/atari/diredsup.c
- # sys/atari/fileio.c
- # sys/atari/gemstart.s
- # sys/atari/getn.s
- # sys/atari/makesys.mwc
- # sys/atari/mg.ini
- # sys/atari/mglink.inp
- # sys/atari/misc.c
- # sys/atari/sysdef.h
- # sys/atari/term.c
- # sys/atari/ttydef.h
- # sys/atari/ttyio.c
- # sys/atari/varargs.h
- # This archive created: Mon May 23 18:14:08 1988
- # By: blarson
- if test -d sys
- then true
- else mkdir sys
- fi
- if test -d sys/atari
- then true
- else mkdir sys/atari
- fi
- cat << \SHAR_EOF > sys/atari/readme.1st
- This file documents the Atari-specific features of MG2A. Please refer
- to the MG manual and the tutorial for more general information about
- how to use MG.
-
- This version of MG has been brought to you by....
-
- Sandra Loosemore (sandra@cs.utah.edu, utah-cs!sandra)
- Marion Hakanson (hakanson@cs.orst.edu, orstcs!hakanson)
-
-
-
- Keyboard Handling:
- ------------------
-
- The ALT key acts as the META key. The command meta-key-mode can be
- used to toggle this behavior. (On non-US keyboards, the ALT key is
- normally used as a modifier with certain other keys to produce printing
- characters.)
-
- MG supports 8-bit characters, although since neither of us have
- European keyboards we have not been able to test this thoroughly.
-
- The function keys may be bound to commands, although there are no
- default bindings established for these keys. F1-F10 are as on the
- keyboard, F11-F20 are the shifted F1-F10, and F21-F28 are Help, Undo,
- Insert, Up, Clr/Home, Left, Down, and Right, respectively.
-
-
- Startup Files:
- --------------
-
- MG looks for its startup file first as MG.INI in the current directory,
- and it then looks for the file specified by the environment variable
- MGINIT if that fails. The code to look up the environment variables
- checks for all of the various environment styles that are supported
- by common shells such as the MWC shell and Gulam, as well as the one
- built for the desktop by GEMBOOT.
-
-
- Spawning a Shell:
- -----------------
-
- The suspend-emacs command checks the SHELL environment variable to
- determine what program to run. If the environment variable is not
- set, or if the attempt to execute the program fails (i.e., the program
- is not found), MG will prompt for a command to execute.
-
-
- Other Options:
- --------------
-
- Most of the optional features described in the MG manual are enabled,
- including the GOSMACS and DIRED features. The major piece of missing
- functionality is the regular expression code, which is nonportable and
- won't compile on the ST. There is also no support for backup files yet.
-
-
- Rebuilding MG:
- --------------
-
- MG has been developed using both the Alcyon (v4.14) and Mark Williams
- (v2.0) C compilers. Makefiles (maketop.mwc and makesys.mwc) are provided
- for MWC, and a Gulam shell script (build.g, also mglink.inp) for Alcyon.
- You may need to tweak these files if you have moved things around.
-
- Here is a list of the ST-specific source files:
-
- chrdef.h Character macro definition file
- sysdef.h ST-specific definitions
- ttydef.h More ST-specific definitions
- varargs.h Definitions for varargs macros
- alloc.c New "malloc" for Alcyon C, also used by MWC.
- cinfo.c Character functions.
- diredsup.c Functions to support the "cd" and "dired" features.
- fileio.c File i/o functions.
- misc.c Functions to support "spawn", etc.
- term.c High-level screen manipulation functions.
- ttyio.c Low-level terminal i/o functions.
- getn.s Functions to determine screen resolution.
- gemstart.s Needed for Alcyon C
-
-
- Changes since MG1B:
- -------------------
-
- File and terminal i/o have been completely rewritten to use low-level
- GemDOS functions instead of their C equivalents. It's now much faster.
-
- Improved memory management (new implementation of "malloc" and friends
- for Alcyon C) makes the "spawn" command more useful.
-
- The use of the ALT key as a meta key and support for 8-bit characters is
- new.
-
- The old "dirlist" function has been replaced by dired mode.
-
- Environment variables are now used to specify the startup file and the
- shell to run for suspend-emacs.
-
- A few minor cleanups and optimizations, some of which speed things
- up markedly.
-
-
- Bugs
- ----
-
- There is a bug in TOS that may result in MG creating multiple copies of
- files with the same name. It only seems to happen with very short files.
-
- There has been some question raised about the use of the "conterm"
- system variable on the "new" (Mega-ST) TOS ROMs, even though such use
- is documented in the MWC manual, and elsewhere. Perhaps someone can
- test this code on such a system and let us know if there are problems.
- A workaround would be to use Getshifts() separately, instead of having
- the kbshift value returned by Bconin().
-
- SHAR_EOF
- cat << \SHAR_EOF > sys/atari/alloc.c
- /* alloc.c -- replacement malloc and friends
- *
- * author : Sandra Loosemore
- * date : 24 Oct 1987
- *
- * This file is a replacement for the usual definitions of malloc and free.
- * The ST Malloc routine is called to get more memory from the system.
- * Note that the memory that is Malloc'ed is never Mfree'd.
- *
- */
-
-
- #include <osbind.h>
- #define NULL 0L
-
-
- /* This is the default size for grabbing memory from the system with Malloc.
- * If you try to malloc a piece bigger than this, it will Malloc a
- * piece exactly the right size. Ideally, it should be quite a bit
- * larger than the average size of things you are allocating (assuming
- * you are going to allocate lots of them).
- */
-
- static long mchunk = 16384L; /* Size for grabbing memory */
-
-
- /* Each call to malloc returns a chunk; freeing it puts the chunk on
- * the free list. The "next" field is only used for freed blocks.
- * The "nbytes" field is the size of the body of the chunk, not
- * the entire chunk.
- */
-
- typedef struct chunk {
- long nbytes;
- union {
- struct chunk *next;
- char body[1];
- } info;
- } CHUNK;
-
- #define Nbytes(c) (c)->nbytes
- #define Next(c) (c)->info.next
- #define Body(c) (c)->info.body
-
- static CHUNK *freelist = NULL;
-
-
- /* Return a block at least "size" bytes long. Grab more memory if there
- * isn't anything on the free list that big. If the block is just big
- * enough, remove it from the free list and return the whole thing.
- * Otherwise, carve a piece off the front.
- * Note that the size is rounded up to make it an even number, and it must
- * also be at least big enough to hold the next pointer when the block
- * is freed.
- */
-
- char *alloc (size)
- long size;
- { register CHUNK *this, *last, *new;
- long temp;
- size = (size + 1) & 0xfffe; /* Word alignment */
- if (size < sizeof(CHUNK *)) size = sizeof(CHUNK *); /* Minimum size */
- this = freelist;
- last = NULL;
- while (this != NULL) {
- if (Nbytes(this) >= size) break;
- last = this;
- this = Next(this);
- }
- if (this == NULL) {
- temp = ((size < mchunk) ? mchunk : size);
- this = (CHUNK *) Malloc (temp + sizeof(long));
- if (!this) return(NULL);
- Nbytes(this) = temp;
- free(Body(this));
- this = freelist;
- last = NULL;
- while (this != NULL) {
- if (Nbytes(this) >= size) break;
- last = this;
- this = Next(this);
- }
- }
- temp = Nbytes(this) - size - sizeof(long);
- if (temp <= sizeof(CHUNK)) { /* Use the whole thing */
- if (last)
- Next(last) = Next(this);
- else
- freelist = Next(this);
- return(Body(this));
- }
- else { /* Grab some off end */
- new = (CHUNK *) ((char *)this + size + sizeof(long));
- Nbytes(new) = temp;
- Next(new) = Next(this);
- if (last)
- Next(last) = new;
- else
- freelist = new;
- Nbytes(this) = size;
- return(Body(this));
- }
- }
-
-
-
- /* These are the user-accessible entry points */
-
- char *malloc (size)
- unsigned size;
- { return (alloc((long)size));
- }
-
- #if 0 /* calloc not used in mg */
- char *calloc (number, size)
- unsigned number, size;
- { return (alloc ((long)number*size));
- }
- #endif
-
- char *realloc (oldptr, newsize)
- register char *oldptr;
- unsigned newsize;
- { long oldsize;
- register char *newptr;
- register unsigned i;
- CHUNK *block;
- block = (CHUNK *) (oldptr - sizeof(long));
- oldsize = Nbytes(block);
- if (newsize > oldsize) {
- newptr = alloc((long)newsize);
- for (i=0; i<oldsize; i++)
- newptr[i] = oldptr[i];
- free(oldptr);
- return(newptr);
- }
- else
- return(oldptr);
- }
-
-
- /* Free a pointer. The freelist is maintained in sorted order, so loop
- * through until we find the block on either side of the one we're
- * freeing. Then see if we can merge this block with either one.
- */
-
- free (ptr)
- char *ptr;
- { register CHUNK *last, *this, *block;
-
- /* Find where to insert the block in the free list. */
-
- block = (CHUNK *)(ptr - sizeof(long));
- this = freelist;
- last = NULL;
- while (this && (this < block)) {
- last = this;
- this = Next(this);
- }
-
- /* Can we merge it with the next block? */
-
- if (this && ((ptr + Nbytes(block)) == this)) {
- Nbytes(block) = Nbytes(block) + Nbytes(this) + sizeof(long);
- Next(block) = Next(this);
- }
- else
- Next(block) = this;
-
- /* Can we merge it with the previous block? */
-
- if (last && ((Body(last) + Nbytes(last)) == block)) {
- Nbytes(last) = Nbytes(last) + Nbytes(block) + sizeof(long);
- Next(last) = Next(block);
- }
- else if (last)
- Next(last) = block;
- else
- freelist = block;
- }
-
-
- /* A debug routine to help me make sure that the freelist is compacted
- * properly.
- */
-
- #ifdef DEBUG
-
- dumpfree ()
- { CHUNK *junk;
- printf ("Dump of free list:\n");
- junk = freelist;
- while (junk) {
- printf (" Base %ld, size %ld\n", (long)(Body(junk)), Nbytes(junk));
- junk = Next(junk);
- }
- }
- #endif
- SHAR_EOF
- cat << \SHAR_EOF > sys/atari/build.g
- # build file for MG using Alcyon C and the GULAM shell
- # execute this from the directory sys\atari
- #
- #
- # First make sure that there are stubs for the include files at top level
- #
- cd ..\..
- if { -e chrdef.h } == 0
- echo '#include "sys\atari\chrdef.h"' > chrdef.h
- endif
- if { -e sysdef.h } == 0
- echo '#include "sys\atari\sysdef.h"' > sysdef.h
- endif
- if { -e ttydef.h } == 0
- echo '#include "sys\atari\ttydef.h"' > ttydef.h
- endif
- if { -e varargs.h } == 0
- echo '#include "sys\atari\varargs.h"' > varargs.h
- endif
- #
- #
- # Recompile all the top-level files
- #
- cc basic
- cc buffer
- cc dir
- cc dired
- cc display
- cc echo
- cc extend
- cc file
- cc help
- cc kbd
- cc keymap
- cc line
- cc macro
- cc main
- cc match
- cc modes
- cc paragrap
- cc random
- cc re_searc
- cc regex
- cc region
- cc search
- cc version
- cc window
- cc word
- #
- #
- # Now do all of the system-specific ones
- #
- cd sys\atari
- cc alloc
- cc cinfo
- cc diredsup
- cc fileio
- cc misc
- cc term
- cc ttyio
- as68 -l -u -s c: gemstart.s
- as68 -l -u -s c: getn.s
- #
- #
- # Now do the link
- #
- aln -c mglink.inp
- SHAR_EOF
- cat << \SHAR_EOF > sys/atari/cinfo.c
- /* cinfo.c -- character class tables for the Atari ST 8-bit character set
- *
- * author : Sandra Loosemore
- * date : 26 Oct 1987
- *
- */
-
- #include "..\..\def.h"
-
- /*
- * This table, indexed by a character drawn
- * from the 256 member character set, is used by my
- * own character type macros to answer questions about the
- * type of a character. It handles the full multinational
- * character set, and lets me ask some questions that the
- * standard "ctype" macros cannot ask.
- */
-
- char cinfo[256] = {
- _C, _C, _C, _C, /* 0x0X */
- _C, _C, _C, _C,
- _C, _C, _C, _C,
- _C, _C, _C, _C,
- _C, _C, _C, _C, /* 0x1X */
- _C, _C, _C, _C,
- _C, _C, _C, _C,
- _C, _C, _C, _C,
- 0, _P, 0, 0, /* 0x2X */
- _W, _W, 0, _W,
- 0, 0, 0, 0,
- 0, 0, _P, 0,
- _W, _W, _W, _W, /* 0x3X */
- _W, _W, _W, _W,
- _W, _W, 0, 0,
- 0, 0, 0, _P,
- 0, _U|_W, _U|_W, _U|_W, /* 0x4X */
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, _U|_W, /* 0x5X */
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, 0,
- 0, 0, 0, 0,
- 0, _L|_W, _L|_W, _L|_W, /* 0x6X */
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, _L|_W, /* 0x7X */
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, 0,
- 0, 0, 0, _C,
- _U|_W, _L|_W, _L|_W, _L|_W, /* 0x8X */
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _U|_W, _U|_W,
- _U|_W, _L|_W, _U|_W, _L|_W, /* 0x9X */
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _U|_W, _U|_W, 0,
- 0, 0, _L|_W, 0,
- _L|_W, _L|_W, _L|_W, _L|_W, /* 0xAX */
- _L|_W, _U|_W, _L|_W, _L|_W,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- _L|_W, _L|_W, _U|_W, _L|_W, /* 0xBX */
- _L|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, 0, 0, 0,
- 0, 0, 0, 0,
- _L|_W, _U|_W, 0, 0, /* 0xCX */
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0, /* 0xDX */
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0, /* 0xEX */
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0, /* 0xFX */
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0
- };
-
-
- /* Convert upper to lower and vice versa. This is borrowed from
- * Bernhard Nebel.
- */
-
- char cupper[256] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
- 0x80, 0x9a, 0x90, 0x41, 0x8e, 0xb6, 0x8f, 0x80,
- 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x8e, 0x8f,
- 0x90, 0x92, 0x92, 0x4f, 0x99, 0x4f, 0x55, 0x55,
- 0x59, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
- 0x41, 0x49, 0x4f, 0x55, 0xa5, 0xa5, 0x41, 0x4f,
- 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
- 0xb7, 0xb8, 0xb2, 0xb2, 0xb5, 0xb5, 0xb6, 0xb7,
- 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
- 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
- 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
- 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
- 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
- 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
- };
-
- char clower[256] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
- 0x87, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x84, 0x86,
- 0x82, 0x91, 0x91, 0x93, 0x94, 0x95, 0x96, 0x97,
- 0x98, 0x94, 0x81, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
- 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
- 0xb0, 0xb1, 0xb1, 0xb3, 0xb4, 0xb4, 0x85, 0xb0,
- 0xb1, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
- 0xc0, 0xc0, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
- 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
- 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
- 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
- 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
- };
-
-
- /*
- * Find the name of a keystroke. Needs to be changed to handle 8-bit printing
- * characters and function keys better. Returns a pointer to the terminating
- * '\0'.
- */
-
- char *keyname(cp, k)
- register char *cp;
- register int k;
- {
- register char *np;
- #ifdef FKEYS
- extern char *keystrings[];
- #endif /* FKEYS */
-
- if(k<0) k &= 0377; /* if char was sign extened */
- switch(k) {
- case CCHR('@'): np = "NUL"; break;
- case CCHR('I'): np = "TAB"; break;
- case CCHR('J'): np = "LFD"; break; /* yuck, but that's what GNU calls it */
- case CCHR('M'): np = "RET"; break;
- case CCHR('['): np = "ESC"; break;
- case ' ': np = "SPC"; break; /* yuck again */
- case CCHR('?'): np = "DEL"; break;
- default:
- #ifdef FKEYS
- if(k >= KFIRST && k <= KLAST &&
- (np = keystrings[k - KFIRST]) != NULL)
- break;
- #endif /* FKEYS */
- if(k > CCHR('?') || k < CCHR('@')) {
- *cp++ = '0';
- *cp++ = ((k>>6)&7) + '0';
- *cp++ = ((k>>3)&7) + '0';
- *cp++ = (k&7) + '0';
- *cp = '\0';
- return cp;
- }
- if(k < ' ') {
- *cp++ = 'C';
- *cp++ = '-';
- k += '@';
- if(ISUPPER(k)) k = TOLOWER(k);
- }
- *cp++ = k;
- *cp = '\0';
- return cp;
- }
- (VOID) strcpy(cp, np);
- return cp + strlen(cp);
- }
- SHAR_EOF
- cat << \SHAR_EOF > sys/atari/diredsup.c
- /* diredsup.c -- Atari ST functions for handling DIR and DIRED features
- *
- * author : Sandra Loosemore
- * date : 20 Dec 1987
- *
- */
-
- #include "..\..\def.h"
-
-
- /* ST-specific code to support the DIR features in dir.c
- */
-
- #ifndef NO_DIR
-
- char *getwd (buffer)
- char *buffer;
- { int drive, i;
- drive = Dgetdrv();
- buffer[0] = (char)drive + 'a';
- buffer[1] = ':';
- Dgetpath (&buffer[2], drive+1);
- for (i=2; buffer[i] != '\0'; i++)
- buffer[i] = TOLOWER(buffer[i]);
- return(buffer);
- }
-
- int chdir (buffer)
- char *buffer;
- { int drive;
- if (buffer[1] == ':') {
- drive = TOLOWER(buffer[0]) - 'a';
- (VOID) Dsetdrv (drive);
- buffer = buffer + 2;
- }
- return ((int)Dsetpath (buffer));
- }
-
- #endif
-
-
- /* ST-specific code to support the DIRED features in dired.c.
- */
-
- #ifndef NO_DIRED
-
- #include "..\..\kbd.h"
-
-
- /* Various file manipulation functions. */
-
- int rename (fromname, toname)
- char *fromname, *toname;
- { if (Frename(0, fromname, toname) == 0)
- return(0);
- else {
- ewprintf ("Rename failed.");
- return(-1);
- }
- }
-
- int copy (fromname, toname)
- char *fromname, *toname;
- { int from, to, count;
- char buffer[256];
- if ((from = Fopen (fromname, 0)) < 0) {
- ewprintf ("Could not open input file %s.", fromname);
- return(-1);
- }
- (VOID) Fdelete (toname);
- if ((to = (Fcreate (toname, 0))) < 0) {
- ewprintf ("Could not open output file %s.", toname);
- Fclose(from);
- return(-1);
- }
- while ((count = Fread(from, (long)256, buffer)) > 0)
- (VOID) Fwrite (to, (long)count, buffer);
- (VOID) Fclose(from);
- (VOID) Fclose(to);
- return(0);
- }
-
- int unlink (fname)
- char *fname;
- { if (Fdelete(fname) == 0)
- return(0);
- else
- return(-1);
- }
-
- int unlinkdir (fname)
- char *fname;
- { if (Ddelete(fname) == 0)
- return(0);
- else
- return(-1);
- }
-
-
- /* Create a dired buffer for the given directory name. */
-
- BUFFER *dired_(dirname)
- char *dirname;
- {
- register BUFFER *bp;
- BUFFER *findbuffer();
-
- /* Create the dired buffer */
-
- if ((dirname = adjustname(dirname)) == NULL) {
- ewprintf("Bad directory name");
- return NULL;
- }
- if ((bp = findbuffer(dirname)) == NULL) {
- ewprintf("Could not create buffer");
- return NULL;
- }
- if (bclear(bp) != TRUE) return FALSE;
-
- /* Now fill it in. */
-
- if (!dirlist (bp, dirname)) {
- ewprintf("Could not read directory");
- return FALSE;
- }
-
- /* Clean up and return */
-
- bp->b_dotp = lforw(bp->b_linep); /* go to first line */
- (VOID) strncpy(bp->b_fname, dirname, NFILEN);
- if((bp->b_modes[0] = name_mode("dired")) == NULL) {
- bp->b_modes[0] = &map_table[0];
- ewprintf("Could not find mode dired");
- return NULL;
- }
- return bp;
- }
-
-
- /* Take the name from the line in the buffer and make a filename out of it.
- */
-
- d_makename(lp, fn)
- register LINE *lp;
- register char *fn;
- {
- register char *cp;
- register char ch;
- int i;
-
- if(llength(lp) < 55) return ABORT;
- (VOID) strcpy (fn, curbp->b_fname);
- cp = fn + strlen(fn);
- *cp++ = '\\';
- i = 2;
- while ((ch = lgetc(lp,i)) != ' ') {
- *cp++ = ch;
- i++;
- }
- *cp = '\0';
- return lgetc(lp, 52) == 'd';
- }
-
-
- /* Here is all the messy code for getting a directory listing.
- * It is printed out like
- *
- * 0 1 2 3 4 5
- * 01234567890123456789012345678901234567890123456789012345
- * name----------><-----size dd-mmm-yyyy hh:mm:ss drw
- *
- */
-
- typedef struct dta {
- char junk[21];
- char attrib;
- unsigned int timestamp;
- unsigned int datestamp;
- long filesize;
- char name[14];
- } DTA;
-
- static char* months[] = {
- "???", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
- "Aug", "Sep", "Oct", "Nov", "Dec"};
-
-
- /* Print a number into the character buffer, bumping up the pointer */
-
- static char* printit (str, number, width, fill, zero)
- char* str;
- long number;
- int width;
- char fill;
- { int i;
- if (number == 0) {
- for (i=1; i<width; i++)
- *str++ = fill;
- if (width == 0)
- ;
- else if (zero)
- *str++ = '0';
- else
- *str++ = fill;
- return (str);
- }
- else {
- str = printit (str, (number/10), width-1, fill, FALSE);
- *str++ = (char) ((number%10) + (int) '0');
- return (str);
- }
- }
-
-
- /* Print a null-terminated string into the buffer */
-
- static char* copyit (to, from, width, fill)
- char *from, *to;
- int width;
- char fill;
- { int i;
- char ch;
- i = 0;
- while (*from != '\0') {
- ch = *from++;
- *to++ = TOLOWER(ch);
- i++;
- }
- while (i < width) {
- *to++ = fill;
- i++;
- }
- return (to);
- }
-
-
- static char* getdate (datestamp, buffer)
- unsigned int datestamp;
- char* buffer;
- { int date, month, year;
-
- date = datestamp & 31;
- month = (datestamp >> 5) & 15;
- year = (datestamp >> 9) + 1980;
- *buffer++ = ' ';
- *buffer++ = ' ';
- buffer = printit (buffer, (long) date, 2, '0', TRUE);
- *buffer++ = '-';
- buffer = copyit (buffer, months[month], 3, ' ');
- *buffer++ = '-';
- buffer = printit (buffer, (long) year, 4, ' ', TRUE);
- return (buffer);
- }
-
-
- static char* gettime (timestamp, buffer)
- unsigned int timestamp;
- char* buffer;
- { int second, minute, hour;
-
- second = (timestamp & 31) * 2;
- minute = (timestamp >> 5) & 63;
- hour = (timestamp >> 11);
- *buffer++ = ' ';
- *buffer++ = ' ';
- buffer = printit (buffer, (long) hour, 2, '0', TRUE);
- *buffer++ = ':';
- buffer = printit (buffer, (long) minute, 2, '0', TRUE);
- *buffer++ = ':';
- buffer = printit (buffer, (long) second, 2, '0', TRUE);
- return (buffer);
- }
-
-
- static dirlist (bp, dirname)
- BUFFER *bp;
- char *dirname;
- {
- char fname[NFILEN], buf[NFILEN];
- int status;
- DTA my_dta, *old_dta;
- char *bufptr;
-
- (VOID) strcpy (fname, dirname);
- (VOID) strcat (fname, "\\*.*");
- old_dta = (DTA *) Fgetdta ();
- Fsetdta (&my_dta);
- status = Fsfirst (fname, 0x11);
- while (status == 0) {
- bufptr = buf;
- *bufptr++ = ' ';
- *bufptr++ = ' ';
- bufptr = copyit (bufptr, my_dta.name, 15, ' ');
- bufptr = printit (bufptr, my_dta.filesize, 10, ' ', TRUE);
- bufptr = getdate (my_dta.datestamp, bufptr);
- bufptr = gettime (my_dta.timestamp, bufptr);
- *bufptr++ = ' ';
- *bufptr++ = ' ';
- *bufptr++ = (my_dta.attrib) ? 'd' : '-'; /* directory */
- *bufptr++ = 'r';
- *bufptr++ = (my_dta.attrib) ? '-' : 'w'; /* read-only */
- *bufptr = '\0';
- if (addline(bp, buf) == FALSE) {
- Fsetdta (old_dta);
- return (FALSE);
- }
- status = Fsnext ();
- }
- Fsetdta (old_dta);
- return (TRUE);
- }
-
- #endif
- SHAR_EOF
- cat << \SHAR_EOF > sys/atari/fileio.c
- /* fileio.c -- Atari ST file system interface for MG
- *
- * author : Sandra Loosemore (from an earlier version by dec-rex!conroy)
- * date : 24 Oct 1987
- * changes: Marion Hakanson -- Jan 1988
- *
- */
- #include "..\..\def.h"
-
-
- /* Adjustname regularizes a filename. This fills in the current drive
- * and directory onto the front if they are not already provided, and
- * also lowercases it so a case-sensitive string compare can be used
- * on filenames.
- * This doesn't do the right things with collapsing "..\" and ".\" -- it
- * doesn't check for them being embedded in pathnames, only at the
- * front. Sigh.
- */
-
- static char adbuffer[128];
-
- char* adjustname (fname)
- char *fname;
- { int i, j, k;
- char pathbuf[128];
-
- if (fname[1] == ':') {
- j = 2;
- adbuffer[0] = TOLOWER(fname[0]);
- }
- else {
- adbuffer[0] = (char)Dgetdrv() + 'a';
- j = 0;
- }
- adbuffer[1] = ':';
- i = 2;
- if (fname[j] != '\\') {
- Dgetpath(pathbuf, (int)(adbuffer[0] - 'a' + 1));
- for (k=0; pathbuf[k] != '\0'; k++) {
- adbuffer[i] = TOLOWER(pathbuf[k]);
- i++;
- }
- adbuffer[i] = '\\';
- i++;
- }
- if (fname[j] == '.') {
- if (fname[j+1] == '.') {
- i = i - 2;
- while (adbuffer[i] != '\\') i--;
- j = j + 2;
- }
- else {
- j = j + 1;
- i = i - 1;
- }
- }
- while (fname[j] != '\0') {
- adbuffer[i] = TOLOWER(fname[j]);
- i++;
- j++;
- }
- adbuffer[i] = '\0';
- return(adbuffer);
- }
-
-
- /* Define some things used later on */
-
- static int handle;
- #define RBUFSIZE 512
- static char rbuffer[RBUFSIZE];
- static int rbufmax, rbufnext, rbufcr;
- static int rbufeof;
-
-
- /* Open and close files. Store the file handle in "handle". We'll use
- * it later in the routines that read and write to the file.
- */
-
-
- ffropen (fn)
- char *fn;
- { handle = Fopen(fn, 0);
- if (handle < 0)
- return(FIOFNF);
- else {
- rbufmax = 0;
- rbufnext = 0;
- rbufcr = FALSE;
- rbufeof = FALSE;
- return(FIOSUC);
- }
- }
-
-
- ffwopen (fn)
- char *fn;
- { (VOID) Fdelete(fn);
- handle = Fcreate(fn, 0);
- if (handle < 0) {
- ewprintf("Open of %s failed with error code %d.", fn, handle);
- return (FIOERR);
- }
- else
- return (FIOSUC);
- }
-
- ffclose ()
- { (VOID) Fclose(handle);
- return (FIOSUC);
- }
-
-
- /* Write an entire buffer to the already open file. The last line of
- * the buffer does not have an implied newline.
- */
-
- static char *crlf = "\r\n";
-
- ffputbuf (buf)
- BUFFER *buf;
- { LINE *line, *last;
-
- last = buf->b_linep; /* Header line is empty */
- line = last->l_fp; /* The first real line */
-
- while (line->l_fp != last) {
- if ((Fwrite (handle, (long)line->l_used, line->l_text) < 0) ||
- (Fwrite (handle, 2l, crlf) < 0)) {
- ewprintf("File write error");
- return (FIOERR);
- }
- line = line->l_fp;
- }
- if (line->l_used > 0) {
- if (Fwrite (handle, (long)line->l_used, line->l_text) < 0) {
- ewprintf("File write error");
- return (FIOERR);
- }
- }
- return(FIOSUC);
- }
-
-
- /* Read a line from the file up to nbuf long. Set *nbytes to the actual
- * count read (excluding the end-of-line marker). Returns:
- * FIOSUC if all is well.
- * FIOLONG if no newline was found yet.
- * FIOEOF on end-of-file.
- * FIOERR if any random errors happened.
- * The GemDos routine Fread does not break on end-of-line; it will read
- * however many characters you tell it to. So we do a little buffering.
- * Remember that crlf is the line terminator. Cr's and lf's that appear
- * by themselves are passed on.
- */
-
-
- ffgetline (buf, nbuf, nbytes)
- char buf[];
- int nbuf;
- int *nbytes;
- { register int i;
- register char ch;
-
- for (i=0; i<nbuf; i++) {
- if (rbufmax == rbufnext) {
- if (rbufeof ||
- ((rbufmax = Fread(handle, (long)RBUFSIZE, rbuffer)) == 0)) {
- (*nbytes) = i;
- return (FIOEOF);
- }
- else if (rbufmax < 0) {
- ewprintf("File read error");
- return (FIOERR);
- }
- else {
- if (rbufmax < RBUFSIZE) rbufeof = TRUE;
- rbufnext = 0;
- }
- }
- ch = rbuffer[rbufnext];
- rbufnext++;
- if (rbufcr && (ch == '\n')) {
- rbufcr = FALSE;
- (*nbytes) = i-1;
- return (FIOSUC);
- }
- else {
- buf[i] = ch;
- rbufcr = (ch == '\r');
- }
- }
- return (FIOLONG);
- }
-
-
- #ifndef NO_BACKUP
-
- /*
- * Finish this routine when you decide
- * what the right thing to do when renaming a
- * file for backup purposes.
- */
-
- fbackupfile(fname)
- char *fname;
- {
- return (TRUE);
- }
-
- #endif
-
-
-
- #ifndef NO_STARTUP
-
- /* Look for a startup file as MG.INI in the current directory, then for
- * the file specified by the environment variable MGINIT.
- */
-
- char* startupfile (ignore)
- char *ignore;
- { int handle;
- char *foo;
- extern char *getenv();
-
- if ((handle = Fopen ("MG.INI", 0)) >= 0) {
- (VOID) Fclose (handle);
- return("MG.INI");
- }
- else if (((foo = getenv("MGINIT")) != NULL) &&
- ((handle = Fopen (foo, 0)) >= 0)) {
- (VOID) Fclose (handle);
- return(foo);
- }
- else
- return(NULL);
- }
-
- #endif
-
- SHAR_EOF
- cat << \SHAR_EOF > sys/atari/gemstart.s
- ******************************************************************************
- *
- * C runtime startup for CP/M-68k.
- *
- ******************************************************************************
- *
- ltpa=0 * Low TPA address
- htpa=4 * High TPA address
- lcode=8 * Code segment start
- codelen=12 * Code segment length
- ldata=16 * Data segment start
- datalen=20 * Data segment length
- lbss=24 * Bss segment start
- bsslen=28 * Bss segment length
- freelen=32 * free segment length
- resvd=36 * Reserved
- fcb2=56 * 2nd parsed fcb
- fcb1=92 * 1st parsed fcb
- command=128 * Command tail
- prtstr=9 * Print string BDOS Call
- exit=0 * BDOS exit call
- .globl __main
- .globl __exit
- .globl __break
- .globl ___cpmrv
- .globl __base
- .globl _sw_
- .globl __sovf
-
-
- .globl _crystal
- .globl _ctrl_cnts
-
-
- .text
-
-
- *
- * Must be first object file in link statement
- *
- move.l a7,a5 * save a7 so we can get the base page address
- move.l 4(a5),a5 * a5=basepage address
- move.l a5,__base * save for C startup
- move.l $c(a5),d0
- add.l $14(a5),d0
- add.l $1c(a5),d0
- add.l #$2000,d0 * d0=basepage+textlen+datalen+bsslen
- * (plus room for user stack)
- move.l d0,d1
- add.l a5,d1 * compute stack top
- and.l #-2,d1 * ensure even byte boundary
- move.l d1,a7 * setup user stack, 1K above end of BSS
-
- move.l d0,-(sp)
- move.l a5,-(sp)
- clr.w -(sp) * junk word
- move #$4a,-(sp) * return excess storage
- trap #1
- add.l #12,sp
-
-
- move.l __base,a0 * Load C external
- move.l lbss(a0),a1 * a1 -> bss region
- adda.l bsslen(a0),a1 * a1 -> 1st heap loc
-
- move.l a1,__break * Put in "break" loc
- lea.l command(a0),a2 * a2 -> command line
- move.b (a2)+,d0 * d0 = byte count
- andi.l #$ff,d0 * clear junk
- move.w d0,-(a7) * push length
- move.l a2,-(a7) * Push commnd
- clr.l a6 * Clear frame pointer
- jsr __main * call main routine
- jmp __exit * call "exit"
-
- *
- * For GEMAES calls from AESBIND.ARC or cryslib.o
- *
- _crystal:
- move.l 4(a7),d1
- move.w #200,d0
- trap #2
- rts
-
- *
- * control array for vdibind
- *
- .data
- .even
- _ctrl_cnts: * Application Manager
- .dc.b 0, 1, 0 * func 010
- .dc.b 2, 1, 1 * func 011
- .dc.b 2, 1, 1 * func 012
- .dc.b 0, 1, 1 * func 013
- .dc.b 2, 1, 1 * func 014
- .dc.b 1, 1, 1 * func 015
- .dc.b 0, 0, 0 * func 016
- .dc.b 0, 0, 0 * func 017
- .dc.b 0, 0, 0 * func 008
- .dc.b 0, 1, 0 * func 019
- * Event Manager
- .dc.b 0, 1, 0 * func 020
- .dc.b 3, 5, 0 * func 021
- .dc.b 5, 5, 0 * func 022
- .dc.b 0, 1, 1 * func 023
- .dc.b 2, 1, 0 * func 024
- .dc.b 16, 7, 1 * func 025
- .dc.b 2, 1, 0 * func 026
- .dc.b 0, 0, 0 * func 027
- .dc.b 0, 0, 0 * func 028
- .dc.b 0, 0, 0 * func 009
- * Menu Manager
- .dc.b 1, 1, 1 * func 030
- .dc.b 2, 1, 1 * func 031
- .dc.b 2, 1, 1 * func 032
- .dc.b 2, 1, 1 * func 033
- .dc.b 1, 1, 2 * func 034
- .dc.b 1, 1, 1 * func 005
- .dc.b 0, 0, 0 * func 006
- .dc.b 0, 0, 0 * func 007
- .dc.b 0, 0, 0 * func 008
- .dc.b 0, 0, 0 * func 009
- * Object Manager
- .dc.b 2, 1, 1 * func 040
- .dc.b 1, 1, 1 * func 041
- .dc.b 6, 1, 1 * func 042
- .dc.b 4, 1, 1 * func 043
- .dc.b 1, 3, 1 * func 044
- .dc.b 2, 1, 1 * func 045
- .dc.b 4, 2, 1 * func 046
- .dc.b 8, 1, 1 * func 047
- .dc.b 0, 0, 0 * func 048
- .dc.b 0, 0, 0 * func 049
- * Form Manager
- .dc.b 1, 1, 1 * func 050
- .dc.b 9, 1, 1 * func 051
- .dc.b 1, 1, 1 * func 002
- .dc.b 1, 1, 0 * func 003
- .dc.b 0, 5, 1 * func 004
- .dc.b 0, 0, 0 * func 005
- .dc.b 0, 0, 0 * func 006
- .dc.b 0, 0, 0 * func 007
- .dc.b 0, 0, 0 * func 008
- .dc.b 0, 0, 0 * func 009
- * Dialog Manager
- .dc.b 0, 0, 0 * func 060
- .dc.b 0, 0, 0 * func 061
- .dc.b 0, 0, 0 * func 062
- .dc.b 0, 0, 0 * func 003
- .dc.b 0, 0, 0 * func 004
- .dc.b 0, 0, 0 * func 005
- .dc.b 0, 0, 0 * func 006
- .dc.b 0, 0, 0 * func 007
- .dc.b 0, 0, 0 * func 008
- .dc.b 0, 0, 0 * func 009
- * Graphics Manager
- .dc.b 4, 3, 0 * func 070
- .dc.b 8, 3, 0 * func 071
- .dc.b 6, 1, 0 * func 072
- .dc.b 8, 1, 0 * func 073
- .dc.b 8, 1, 0 * func 074
- .dc.b 4, 1, 1 * func 075
- .dc.b 3, 1, 1 * func 076
- .dc.b 0, 5, 0 * func 077
- .dc.b 1, 1, 1 * func 078
- .dc.b 0, 5, 0 * func 009
- * Scrap Manager
- .dc.b 0, 1, 1 * func 080
- .dc.b 0, 1, 1 * func 081
- .dc.b 0, 0, 0 * func 082
- .dc.b 0, 0, 0 * func 083
- .dc.b 0, 0, 0 * func 084
- .dc.b 0, 0, 0 * func 005
- .dc.b 0, 0, 0 * func 006
- .dc.b 0, 0, 0 * func 007
- .dc.b 0, 0, 0 * func 008
- .dc.b 0, 0, 0 * func 009
- * fseler Manager
- .dc.b 0, 2, 2 * func 090
- .dc.b 0, 0, 0 * func 091
- .dc.b 0, 0, 0 * func 092
- .dc.b 0, 0, 0 * func 003
- .dc.b 0, 0, 0 * func 004
- .dc.b 0, 0, 0 * func 005
- .dc.b 0, 0, 0 * func 006
- .dc.b 0, 0, 0 * func 007
- .dc.b 0, 0, 0 * func 008
- .dc.b 0, 0, 0 * func 009
- * Window Manager
- .dc.b 5, 1, 0 * func 100
- .dc.b 5, 1, 0 * func 101
- .dc.b 1, 1, 0 * func 102
- .dc.b 1, 1, 0 * func 103
- .dc.b 2, 5, 0 * func 104
- .dc.b 6, 1, 0 * func 105
- .dc.b 2, 1, 0 * func 106
- .dc.b 1, 1, 0 * func 107
- .dc.b 6, 5, 0 * func 108
- .dc.b 0, 0, 0 * func 009
- * Resource Manger
- .dc.b 0, 1, 1 * func 110
- .dc.b 0, 1, 0 * func 111
- .dc.b 2, 1, 0 * func 112
- .dc.b 2, 1, 1 * func 113
- .dc.b 1, 1, 1 * func 114
- .dc.b 0, 0, 0 * func 115
- .dc.b 0, 0, 0 * func 006
- .dc.b 0, 0, 0 * func 007
- .dc.b 0, 0, 0 * func 008
- .dc.b 0, 0, 0 * func 009
- * Shell Manager
- .dc.b 0, 1, 2 * func 120
- .dc.b 3, 1, 2 * func 121
- .dc.b 1, 1, 1 * func 122
- .dc.b 1, 1, 1 * func 123
- .dc.b 0, 1, 1 * func 124
- .dc.b 0, 1, 2 * func 125
-
- .bss
- .even
- __base: .ds.l 1 * -> Base Page
- __break: .ds.l 1 * Break function
- ___cpmrv: .ds.w 1 * Last CP/M return val
-
-
-
- *
- *
- .globl _brk
- .text
- _brk:
- movea.l 4(sp),a0 * New break?
- move.l a0,d0
- lea $100(a0),a0 * Chicken factor
- cmpa.l a0,sp * Compare
- bhis brkok * OK, continue
- move.l #-1,d0 * Load return reg
- rts * Return
- brkok:
- move.l d0,__break * Save the break
- clr.l d0 * Set OK return
- rts * return
-
- .globl ___BDOS
- ___BDOS: link a6,#0 * link
- move.w 8(sp),d0 * Load func code
- move.l 10(sp),d1 * Load Paramter
- trap #2 * Enter BDOS
- cmpa.l __break,sp * Check for stack ovf
- bhis noovf * NO overflow, continue
- __sovf: move.w #prtstr,d0 * String print
- lea ovf,a0 * a0-> message
- move.l a0,d1 * load proper reg
- trap #2 * Issue message
- __exit: move.w #exit,d0 * Exit
- trap #2 * now
- noovf: * Here if all OK
- unlk a6 *
- rts * Back to caller
- *
- * Block Fill function:
- *
- * blkfill(dest,char,cnt);
- *
- * BYTE *dest; /* -> area to be filled */
- * BYTE char; /* = char to fill */
- * WORD cnt; /* = # bytes to fill */
- *
- .globl _blkfill
- _blkfill:
- move.l 4(a7),a0 * -> Output area
- move.w 8(a7),d1 * = output char
- move.w 10(a7),d0 * = output count
- ext.l d0 * make it long
- subq.l #1,d0 * decrement
- ble filldone * Done if le
- fillit: move.b d1,(a0)+ * move a byte
- dbra d0,fillit * Continue
- filldone: clr.l d0 * always return 0
- rts *
-
- *
- * Index function to find out if a particular character is in a string.
- *
- .globl _index
- .globl _strchr
- _index:
- _strchr:
- move.l 4(a7),a0 * a0 -> String
- move.w 8(a7),d0 * D0 = desired character
- xindex: tst.b (a0) * EOS?
- bne notend * No, continue to look
- clr.l d0 * Not found
- rts * Quit
- notend: cmp.b (a0)+,d0 * check for character
- bne xindex *
- move.l a0,d0 * Found it
- subq.l #1,d0 * set return pointer
- rts *
- *
- * Data area
- *
- .data
- .globl ___pname * Program Name
- .globl ___tname * Terminal Name
- .globl ___lname * List device name
- .globl ___xeof * ^Z byte
- ovf: .dc.b 'Stack Overflow$' * Error message
- ___pname: .dc.b 'C runtime',0 * Program name
- ___tname: .dc.b 'CON:',0 * Console name
- ___lname: .dc.b 'LST:',0 * List device name
- ___xeof: .dc.b $1a * Control-Z
- .end
- SHAR_EOF
- cat << \SHAR_EOF > sys/atari/getn.s
- * Routines to read the size of the display.
- * MicroEMACS works even on a screen that has been blessed
- * by the "hi50" program.
- * MicroEMACS version 30, for the Atari.
-
- .text
-
- * getnrow() -- get number of rows.
-
- .globl _getnrow
-
- _getnrow:
-
- move.l a2, -(sp)
- move.l d2, -(sp)
- dc.w $A000
- move.l (sp)+, d2
- movea.l (sp)+, a2
-
- move.w -42(a0), d0
- addq.w #1, d0
- ext.l d0
-
- rts
-
- * getncol() -- get number of columns.
-
- .globl _getncol
-
- _getncol:
- move.l a2, -(sp)
- move.l d2, -(sp)
- dc.w $A000
- move.l (sp)+, d2
- movea.l (sp)+, a2
-
- move.w -44(a0), d0
- addq.w #1, d0
- ext.l d0
-
- rts
- SHAR_EOF
- cat << \SHAR_EOF > sys/atari/makesys.mwc
- #
- # MWC Makefile for MG (Atari ST) -- system library
- #
- # Marion Hakanson Jan '88
-
- # Note that this Makefile expects the sources to be in ..\..\,
- # as do the source files here.
-
- # SYSLIB and CFLAGS should be defined by the top level Makefile.
- # These are defaults in case this Makefile is called manually.
- SYSLIB = libsys.a
-
- CDEFS = -DPREFIXREGION
- CFLAGS = -O -DMWC $(CDEFS)
-
- OBJ = cinfo.o fileio.o misc.o term.o ttyio.o
- IND = diredsup.o alloc.o getn.o
- OBJS = $(OBJ) $(IND)
- INC = ..\..\def.h
- OINC = chrdef.h sysdef.h ttydef.h
-
-
- all: $(SYSLIB)
- @echo $(SYSLIB) completed.
-
- $(SYSLIB): $(OBJS)
- ar rcv $@ $?
-
-
- $(OBJ): $(INC) $(OINC)
-
- diredsup.o: $(INC) $(OINC) ..\..\kbd.h
-
- getn.o: getn.s
- as68toas < $? > tmp.s; $(AS) $(ASFLAGS) -o $@ tmp.s; rm tmp.s
-
-
- clean:
- -rm $(OBJS) tmp.s $(SYSLIB)
-
- SHAR_EOF
- cat << \SHAR_EOF > sys/atari/mg.ini
- (bsmap-mode 1) ; enable
- ; auto-indent globally
- (global-set-key "\^J" newline)
- (global-set-key "\^M" newline-and-indent)
- ; blink-matching-paren globally
- (global-set-key ")" blink-matching-paren-hack)
- (global-set-key "}" blink-matching-paren-hack)
- (global-set-key "]" blink-matching-paren-hack)
- ; set up special keys (ST)
- (global-set-key "\F21" help)
- (global-set-key "\F21\F21" help-help)
- (global-set-key "\F22" keyboard-quit)
- (global-set-key "\F24" previous-line)
- (global-set-key "\F26" backward-char)
- (global-set-key "\F27" next-line)
- (global-set-key "\F28" forward-char)
- SHAR_EOF
- cat << \SHAR_EOF > sys/atari/mglink.inp
- -u -o ..\..\mg.ttp gemstart.o
- ..\..\basic.o
- ..\..\buffer.o
- ..\..\dir.o
- ..\..\dired.o
- ..\..\display.o
- ..\..\echo.o
- ..\..\extend.o
- ..\..\file.o
- ..\..\help.o
- ..\..\kbd.o
- ..\..\keymap.o
- ..\..\line.o
- ..\..\macro.o
- ..\..\main.o
- ..\..\match.o
- ..\..\modes.o
- ..\..\paragrap.o
- ..\..\random.o
- ..\..\re_searc.o
- ..\..\regex.o
- ..\..\region.o
- ..\..\search.o
- ..\..\version.o
- ..\..\window.o
- ..\..\word.o
- alloc.o
- cinfo.o
- diredsup.o
- fileio.o
- misc.o
- term.o
- ttyio.o
- getn.o
- C:osbind.o c:gemlib c:libf
- SHAR_EOF
- cat << \SHAR_EOF > sys/atari/misc.c
- /* misc.c -- Miscellaneous ST-specific code for MG.
- *
- * author : Sandra Loosemore
- * date : 24 Oct 1987
- * changes: Marion Hakanson -- Jan 1988
- *
- */
-
-
- #include "..\..\def.h"
-
- #ifdef MWC
- static char *
- mwc_cpr="Portions of this program, copyright 1984, Mark Williams Co.";
- #endif /* MWC */
-
-
- /* Exit as quickly as possible. */
-
- VOID panic (s)
- char* s;
- { Cconws (s);
- Pterm (-1);
- }
-
-
- #ifdef MWC
- extern char **environ;
- #else
- typedef struct
- {
- char *p_lowtpa;
- char *p_hitpa;
- char *p_tbase;
- long p_tlen;
- char *p_dbase;
- long p_dlen;
- char *p_bbase;
- long p_blen;
- char *p_dta;
- char *p_parent;
- char *p_reserved;
- char *p_env;
- long p_undefined[20];
- char p_cmdlin[128];
- }
- BASEPAGE;
-
- extern BASEPAGE *_base;
- #endif /* MWC */
-
-
- /*
- * The environment code here is borrowed from Dale Schumacher.
- */
-
- static char *findenv(var)
- register char *var;
- /*
- * INTERNAL FUNCTION. This functions attempts to locate <var> in
- * the environment. If <var> is not found, NULL is returned. If
- * the environment is NULL, NULL is returned. If <var> is found,
- * a pointer to the beginning of <var> in the environment is returned.
- * BOTH MS-DOS AND TOS ENVIRONMENT FORMATS ARE ACCOMODATED.
- */
- {
- register char *p;
- register int len;
-
- #ifdef MWC
- if((p = *environ) == NULL)
- #else
- if((p = _base->p_env) == NULL)
- #endif /* MWC */
- return(NULL);
- len = strlen(var);
- while(*p)
- {
- if(!strncmp(p, var, len) && (p[len] == '='))
- return(p);
- while(*p++) /* move to next arg */
- ;
- }
- return(NULL);
- }
-
-
- char *getenv(var)
- register char *var;
- /*
- * Search for <var> in the environment. If <var> is found, a pointer
- * to it's value is returned. NULL is returned if <var> is not found.
- * WARNING: The returned pointer points into the environment and
- * must not be modified!
- */
- {
- register char *p, *q;
- register int len;
-
- len = strlen(var);
- if(p = findenv(var))
- {
- p += (len + 1);
- if(*p == '\0') /* TOS env format or empty value */
- {
- q = p+1;
- if(*q == '\0') /* empty value + end of env */
- return(p);
- while(*q && (*q != '='))
- ++q;
- if(*q) /* empty value */
- return(p);
- else /* TOS env format */
- return(p+1);
- }
- }
- return(p);
- }
-
-
- /* Spawn a command. You can run anything from this; it prompts you for
- * the command to run.
- * I check for the two most common problems with Pexec: not finding the
- * file, and not having enough memory. Otherwise, I assume bad status
- * codes were the fault of the program, not Pexec, and that the program
- * would have told the user what is wrong.
- */
-
- spawncli(f, n)
- { register int s;
- char fname[NFILEN];
- char tail[NFILEN];
- char *shell = getenv("SHELL");
- extern VOID splitcmd();
-
- if (shell && *shell) {
- (VOID) strcpy(fname, shell);
- goto tryit;
- }
- else
- shell = NULL;
-
- askfor:
- if ((s = ereply("Run program: ", fname, NFILEN)) != TRUE)
- return (s);
- tryit:
- ttcolor (CTEXT);
- ttmove (nrow-1, 0);
- tteeol ();
- splitcmd (fname, tail);
- ttclose ();
- s = Pexec(0, fname, tail, 0L);
- ttopen ();
- if (s == -33) {
- if (shell) {
- shell = NULL;
- ewprintf ("Could not find shell.");
- sleep(1);
- goto askfor;
- }
- ewprintf ("Could not find file.");
- return (FALSE);
- }
- else if (s == -39) {
- if (shell) {
- shell = NULL;
- ewprintf ("Not enough memory to run shell!");
- sleep(1);
- goto askfor;
- }
- ewprintf ("Not enough memory to run this program!");
- return (FALSE);
- }
- else {
- sgarbf = TRUE; /* Force repaint */
- Cconws ("Hit any key to return to MG:");
- (VOID) Crawcin ();
- return (TRUE);
- }
- }
-
-
- /* Pexec wants the command tail to have a byte count as the first
- * character. This function separates the program name from the command
- * tail and adds the byte count.
- */
-
- static VOID splitcmd (cmd, tail)
- char* cmd;
- char* tail;
- { int i, j;
- i = 0;
- j = 0;
- while (cmd[i] != '\0') {
- if (j != 0) {
- tail[j] = cmd[i];
- j++;
- }
- else if (cmd[i] == ' ') {
- cmd[i] = '\0';
- tail[1] = ' ';
- j = 2;
- }
- i++;
- }
- if (j == 0) {
- tail[0] = (char) 1;
- tail[1] = ' ';
- tail[2] = '\0';
- }
- else {
- tail[j+1] = '\0';
- tail[0] = (char) (j-1);
- }
- }
-
-
-
-
- /*
- * copy 'count' bytes from 'src' to 'dst'. (optimized)
- */
- VOID bcopy(src, dst, count)
- register char *src, *dst;
- register count;
- {
- register c1;
-
- /*
- ** The magic number 8 comes from:
- ** 1 max. bytes before a word boundary
- ** 4 min. bytes in a block of long-words
- ** 3 max. bytes after the last long-word in the block
- */
- if (count >= 8) {
- /*
- ** Advance dst pointer to word boundary.
- */
- if (1 & (short)dst) {
- *dst++ = *src++;
- count--;
- }
- /*
- ** If src pointer is (also) aligned, use long-word copy.
- */
- if ((1 & (short)src) == 0) {
- c1 = ((unsigned)count >> 2);
- while (--c1 >= 0)
- *((long *)dst)++ = *((long *)src)++;
- count &= 3; /* There are 0,1,2, or 3 bytes left */
- }
- }
- /*
- ** Copy whatever is left.
- */
- while (--count >= 0)
- *dst++ = *src++;
- }
-
- /* Busy waiting to fake out sleep. Thanks to Rich Sansom for the routine
- * to poll the system clock.
- */
-
- static long *hz_200 = (long *)0x000004ba; /* system 200 hz clock */
-
- #ifdef NO_DPROMPT
- static long read200hz()
- #else
- long read200hz()
- #endif /* NO_DPROMPT */
- { return(*hz_200);
- }
-
-
- /* Sleep (busily) for n seconds */
-
- sleep (n)
- int n;
- { register long waitfor = (n * 200) + Supexec(read200hz);
-
- while (Supexec(read200hz) < waitfor);
- }
-
- SHAR_EOF
- cat << \SHAR_EOF > sys/atari/sysdef.h
- /* sysdef.h -- MG header file for Atari ST
- *
- * author : Sandra Loosemore
- * date : 24 Oct 1987
- *
- */
-
- #define NULL 0L /* So who needs stdio.h? */
- #include <osbind.h>
-
- /* This definition might be missing from your osbind.h */
-
- #ifndef Supexec
- #define Supexec(a) xbios(38,a)
- #endif
-
-
- #define KBLOCK 512 /* Kill grow. */
- #define GOOD 0 /* Good exit status. */
- #define NO_VOID_TYPE 1 /* "void" is not a builtin type */
- #ifdef MWC
- #undef NO_VOID_TYPE
- #define ZEROARRAY /* See def.h */
- /*
- * Using the MWC shell, ARGV is always the last environment entry
- * (if ARGV is not defined, the program was not started from the
- * MWC shell). The last environment variable is followed by
- * the string pointed to by argv[0], then argv[1], etc. This
- * means that the non-MWC getenv() in misc.c will take command line
- * args as environment variables. It also means that if spawn()
- * (misc.c) runs the MWC shell, the shell takes this program's args
- * as its own. So here we truncate the environment by zeroing out
- * the first character of argv[0], thus working around both problems.
- */
- #define SYSINIT (*(argv[0]) = 0) /* run in main() */
- #endif /* MWC */
-
- #define MALLOCROUND(m) ((m)+=1,(m)&=~1) /* 2-byte blocks (see alloc.c) */
- #define LOCAL_VARARGS 1 /* For echo.c */
- #define RSIZE long /* Type for file/region sizes */
- #define KCHAR int /* 16 bits for keystrokes */
-
-
- /* Enable various things */
-
- #define DO_METAKEY 1 /* Meta key code */
- #define METABIT 0x200
- #define FKEYS 1 /* Enable fkey code */
- #define GOSMACS 1 /* Goslings compatibility functions */
- #define PREFIXREGION 1 /* Enable prefix-region function */
- #define BSMAP FALSE /* BSMAP code, default to off */
-
- /* Disable some features for now. */
-
- #define NO_BACKUP 1
-
-
- /* Alcyon thinks subtracting two pointers gives a long. Cast it to int.
- */
-
- #define OFFSET(type,member) ((int)((char *)&(((type *)0)->member)-(char *)((type *)0)))
- #ifdef MWC
- #undef OFFSET
- #endif /* MWC */
-
- /*
- * Macros used by the buffer name making code.
- * Start at the end of the file name, scan to the left
- * until BDC1 (or BDC2, if defined) is reached. The buffer
- * name starts just to the right of that location, and
- * stops at end of string (or at the next BDC3 character,
- * if defined). BDC2 and BDC3 are mainly for VMS.
- */
-
- #define BDC1 '\\' /* Buffer names. */
- #define BDC2 ':'
-
-
- #define fncmp strcmp /* All filenames are lowercased */
- extern char *strncpy();
-
- SHAR_EOF
- cat << \SHAR_EOF > sys/atari/term.c
- /* term.c -- screen output code for Atari ST terminal
- *
- * author : Sandra Loosemore (based on an earlier version by dec-rec!conroy)
- * date : 24 Oct 1987
- * changes: Marion Hakanson -- Jan 1988
- *
- * This code simulates scrolling regions by using the
- * insert line and delete line functions. Should display
- * handling be taught about this. Based on Rich's code
- * for the Heath H19.
- */
-
- #include "..\..\def.h"
-
- #define BEL 0x07 /* BEL character. */
- #define ESC 0x1B /* ESC character. */
- #define LF 0x0A /* Line feed. */
-
- extern int ttrow;
- extern int ttcol;
- extern int tttop;
- extern int ttbot;
- extern int tthue;
-
- int tceeol = 2; /* Costs. */
- int tcinsl, tcdell; /* Set in ttyio.c:ttopen() */
-
-
- /* Move the cursor to the specified origin 0 row and column position. Try
- * to optimize out extra moves; redisplay may have left the cursor in
- * the right location on the screen last time.
- */
-
- VOID ttmove(row, col)
- { if (ttrow!=row || ttcol!=col) {
- if (row > nrow)
- row = nrow;
- if (col > ncol)
- col = ncol;
- ttputc(ESC);
- ttputc('Y');
- ttputc(row+' ');
- ttputc(col+' ');
- ttrow = row;
- ttcol = col;
- }
- }
-
-
- /* Erase to end of line. */
-
- VOID tteeol()
- { ttputc(ESC);
- ttputc('K');
- }
-
-
- /* Erase to end of page. */
-
- VOID tteeop()
- { ttputc(ESC);
- ttputc('J');
- }
-
-
- /* Make a noise. */
-
- VOID ttbeep()
- { ttputc(BEL);
- ttflush();
- }
-
-
- /* Insert nchunk blank line(s) onto the screen, scrolling the last line on
- * the screen off the bottom. This is done with a cluster of clever
- * insert and delete commands, because there are no scroll regions.
- */
-
- VOID ttinsl(row, bot, nchunk)
- { register int i;
- if (row == bot) {
- ttmove(row, 0);
- tteeol();
- return;
- }
- ttmove(1+bot-nchunk, 0);
- for (i=0; i<nchunk; i++) {
- ttputc(ESC);
- ttputc('M');
- }
- ttmove(row, 0);
- for (i=0; i<nchunk; i++) {
- ttputc(ESC);
- ttputc('L');
- }
- ttrow = row;
- ttcol = 0;
- }
-
-
- /* Delete nchunk line(s) at "row", replacing the bottom line on the screen
- * with a blank line. This is done with a crafty sequences of insert
- * and delete line sequences since there is no scroll region. The
- * presence of the echo area makes a boundary condition go away.
- */
-
- VOID ttdell(row, bot, nchunk)
- { register int i;
- if (row == bot) {
- ttmove(row, 0);
- tteeol();
- return;
- }
- ttmove(row, 0);
- for (i=0; i<nchunk; i++) {
- ttputc(ESC);
- ttputc('M');
- }
- ttmove(1+bot-nchunk,0);
- for (i=0; i<nchunk; i++) {
- ttputc(ESC);
- ttputc('L');
- }
- ttrow = 1+bot-nchunk;
- ttcol = 0;
- }
-
-
- /* Set display color. Normal video is text color. Reverse video is used
- * for the mode line.
- */
-
- VOID ttcolor(color)
- register int color;
- { if (color != tthue) {
- if (color == CTEXT) { /* Normal video. */
- ttputc(ESC);
- ttputc('q');
- }
- else if (color == CMODE) { /* Reverse video. */
- ttputc(ESC);
- ttputc('p');
- }
- tthue = color;
- }
- }
- SHAR_EOF
- cat << \SHAR_EOF > sys/atari/ttydef.h
- /*
- * Name: MicroEMACS
- * Atari 520ST header file.
- * Version: 30
- * Last edit: 22-Feb-86
- * By: rex::conroy
- * decvax!decwrl!dec-rhea!dec-rex!conroy
- */
- #define GOSLING 1 /* Use fancy redisplay. */
-
- #define NROW 50 /* The "50" is big enough to */
- #define NCOL 80 /* deal with the "hi50" screen. */
-
- /*
- * Special keys.
- */
-
- #define KFIRST 256
- #define KLAST 284
-
-
- /* These i/o functions are NOP's or direct equivalents of BIOS calls.
- * Make them #define's so we don't have to go through a useless
- * level of indirection.
- */
-
- #define ttinit()
- #define tttidy()
- #define ttwindow(top,bot) (top, bot)
- #define ttresize()
- #define ttnowindow()
- #define ttputc(c) Bconout(2, c) /* Primitive output function */
- #define ttflush() /* A NOP */
- #define typeahead() ((int)Bconstat(2)) /* Check if there is input */
- SHAR_EOF
- cat << \SHAR_EOF > sys/atari/ttyio.c
- /* ttyio.c -- Low-level Atari ST terminal input/output handling
- *
- * author : Sandra Loosemore (from an earlier version by dec-rex!conroy)
- * date : 24 Oct 1987
- * changes: Marion Hakanson -- Jan 1988
- *
- */
-
- #include "..\..\def.h"
-
- int nrow; /* Terminal size, rows. */
- int ncol; /* Terminal size, columns. */
-
- #ifdef DO_METAKEY
- #define RSHIFT (0x01)
- #define LSHIFT (0x02)
- #define CTRL (0x04)
- #define ALTKEY (0x08)
- #define CAPSLOCK (0x10)
-
- static struct keytab {
- char *unshift;
- char *shift;
- char *capslock;
- } *keytable;
-
-
- /* Mess with the bit that controls whether we get back all the shift keys
- * on each keystroke.
- */
-
- static unsigned char oldconterm;
- static unsigned char *conterm = (char *)0x00000484;
-
- static savect ()
- { oldconterm = *conterm;
- *conterm = (oldconterm | 0x8);
- }
-
- static restct ()
- { *conterm = oldconterm;
- }
- #endif /* DO_METAKEY */
-
-
- /* Setup routines. "getnrow" and "getncol" are assembly language routines.
- */
-
- VOID ttopen()
- { nrow = getnrow();
- if (nrow > NROW)
- nrow = NROW;
- ncol = getncol();
- if (ncol > NCOL)
- ncol = NCOL;
- tcinsl = tcdell = (nrow * 2) + (ncol / 10);
- #ifdef DO_METAKEY
- (VOID) Supexec(savect);
- keytable = (struct keytab *)Keytbl(-1L,-1L,-1L);
- #endif /* DO_METAKEY */
- }
-
- VOID ttclose()
- {
- #ifdef DO_METAKEY
- (VOID) Supexec(restct);
- #endif /* DO_METAKEY */
- }
-
-
- /* Keystrokes are returned as 10-bit quantities.
- *
- * Codes 0-255 are used for the usual character set.
- * Codes 256-511 are used for function keys.
- * Bit 10 (0x200) is the meta bit.
- *
- */
- #ifdef FKEYS
-
- static int keycodes[] = {
- 0x00, /* dummy for F0 entry */
- 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- 0x40, 0x41, 0x42, 0x43, 0x44,
- 0x54, 0x55, 0x56, 0x57, 0x58,
- 0x59, 0x5a, 0x5b, 0x5c, 0x5d,
- 0x62, 0x61, 0x52, 0x48, 0x47,
- 0x4b, 0x50, 0x4d
- };
-
- char *keystrings[] = {
- "", /* dummy for F0 entry */
- "F1", "F2", "F3", "F4", "F5",
- "F6", "F7", "F8", "F9", "F10",
- "F11", "F12", "F13", "F14", "F15",
- "F16", "F17", "F18", "F19", "F20",
- "Help", "Undo", "Insert", "Up", "Clr/Home",
- "Left", "Down", "Right"
- };
- #endif /* FKEYS */
-
- /* Use the ALT key as a meta key. The problem with this is that it
- * appears to trash the ascii key code in the low order byte.
- * Therefore, we have to resort to looking up the key in the
- * system keystroke translation table.
- * Some non-US keyboards apparently use some ALT combinations to
- * get real, printing characters. If you've got one of these
- * beasts you can use meta-key-mode to turn off recognition
- * of the ALT key, in which case this routine just returns
- * whatever BIOS gave as the key value. If that approach is
- * distasteful, you can also bind a function key to return
- * the ALT characters usurped by the meta key mode.
- */
-
- KCHAR getkbd()
- { register int code, bchar;
- #ifdef FKEYS
- register int i;
- #endif /* FKEYS */
- #ifdef DO_METAKEY
- register int shifts;
- extern int use_metakey; /* set in the generic kbd.c */
- #endif /* DO_METAKEY */
- union {
- unsigned long k_rawkey;
- struct {
- unsigned char kb_shifts; /* shift bits */
- unsigned char kb_code; /* scan code */
- unsigned char kb_notused;
- unsigned char kb_bchar; /* bios char */
- } k_break;
- } keyval;
-
- keyval.k_rawkey = Bconin(2);
- code = keyval.k_break.kb_code;
-
- #ifdef FKEYS
- for (i=KFIRST; i<=KLAST; i++) /* Was it an Fkey? */
- if (code == keycodes[i-KFIRST])
- return((KCHAR)i);
- #endif /* FKEYS */
-
- bchar = keyval.k_break.kb_bchar;
- #ifdef DO_METAKEY
- shifts = keyval.k_break.kb_shifts;
-
- /*
- * Rule out the case where some shift bit other than what
- * we're interested in is set (if such a beast ever exists).
- * If otherwise, just forget about any special handling here.
- */
- if (use_metakey == TRUE &&
- (shifts & ~(CTRL|LSHIFT|RSHIFT|CAPSLOCK)) == ALTKEY)
- if ((shifts & (CTRL|LSHIFT|RSHIFT|CAPSLOCK)) == 0) /* ALTKEY only */
- return ((KCHAR)(keytable->unshift[code] | METABIT));
- else if (shifts & CTRL)
- return ((KCHAR)(bchar | METABIT));
- else if (shifts & (LSHIFT|RSHIFT))
- return ((KCHAR)(keytable->shift[code] | METABIT));
- else /* (shifts & CAPSLOCK) */
- return ((KCHAR)(keytable->capslock[code] | METABIT));
- else
- return ((KCHAR)bchar);
- #else
- return ((KCHAR)bchar);
- #endif
- }
-
- /* Establish default keypad bindings. I've only done the arrow keys
- * here.
- */
-
-
- VOID ttykeymapinit() {
- /* excline("global-set-key f13 previous-line"); */ /* Up arrow */
- /* excline("global-set-key f15 backward-char"); */ /* Left arrow */
- /* excline("global-set-key f16 next-line"); */ /* Down arrow */
- /* excline("global-set-key f17 forward-char"); */ /* Right arrow */
- }
-
-
- #ifndef NO_DPROMPT
- /*
- * Return TRUE if we busy-wait for 2 seconds without any keystrokes;
- * otherwise return FALSE. See sleep() in misc.c for details.
- */
-
- ttwait() {
- extern long read200hz();
- register keyhit;
- register long waitfor = 400L + Supexec(read200hz);
-
- while ((keyhit = typeahead()) == 0 && Supexec(read200hz) < waitfor);
- if (keyhit)
- return FALSE;
-
- return TRUE;
- }
- #endif /* NO_DPROMPT */
-
-
- SHAR_EOF
- cat << \SHAR_EOF > sys/atari/varargs.h
- /*
- * Varargs, for use on Atari ST (works with MWC, probably others).
- * Came from AmigaDOS version, which was borrowed from 4BSD.
- */
-
- typedef char *va_list;
- #define va_dcl int va_alist;
- #define va_start(pv) pv = (char *) &va_alist
- #define va_end(pv) /* Naught to do... */
- #define va_arg(pv, t) ((t *) (pv += sizeof(t)))[-1]
- SHAR_EOF
- # End of shell archive
- exit 0
- -------
-