[comp.sources.amiga] CoreWars--the classic game, for the Amiga. Part 1 of 1

ahh@j.cc.purdue.edu (Brent L. Woods) (04/24/88)

Program Name:  CoreWars

Submitted By:  Chad_The-Walrus_Netzer@cup.portal.com

Summary:  An implementation of the classic game "Corewars" (in which two
          players pit two deliberately destructive programs against one
          another.

Poster Boy:  Brent Woods  (ahh@j.cc.purdue.edu)

Tested.

NOTES:  No documentation (see the readme file) but that's not too much
        of a handicap.



Brent Woods, Co-Moderator, comp.{sources,binaries}.amiga

USENET:  ...!j.cc.purdue.edu!ahh     ARPANET:  ahh@j.cc.purdue.edu
BITNET:  PODUM@PURCCVM               PHONE:  +1 (317) 743-8421
USNAIL:  320 Brown St., #406  /  West Lafayette, IN  47906

================================================================

#	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:
#	README.1st
#	IMP
#	DWARF
#	corewar.c
#	corewar.h
#	CoreOLD.c
#	makefile
# This archive created: Sat Jan 16 20:29:11 1988
echo shar: extracting README.1st
sed 's/^XX//' << \SHAR_EOF > README.1st
XX
XX	Amiga CoreWars -- 1.01w  Ported by Chad 'The_Walrus' Netzer
XX
XX	This version released on February 29th, 1988 (Leap Year! :-)
XX
XX	Here is a (preliminary) version of the game "CoreWars" for the
XXAmiga computer.  If you haven't heard of the game "CoreWars" before, I
XXrefer you to the May 1984 issue of Scientific American.  Look for the
XXarticle in A.K.  Dewdney's 'Computer Recreations' column.  I would have
XXliked to include docs for the game itself, with this program, but they
XXare long, and I don't really want to re-type them.  (This whole project
XXis for relaxation, and I don't have the time to do a good manual. 
XXPerhaps someone else will...).
XX	This program is NOT public domain, but is freely
XXredistributable, as long as it is not for commercial purposes.  You MUST
XXinclude this document file , the executable program itself, and ALL
XXsources together with any distributuion, or at least make all the
XXmaterials available somewhere...  I give permission to include these
XXfiles on any Fish disks, or other PD software libraries (Fish, Amicus,
XXAUGment disks, FAUG library, etc...)
XX
XX	To use this program, type "run corewars", and it will (sort of)
XXguide you through its operation.  Most importantly, the program can be
XXaborted at any time by pressing CTRL-C, CTRL-\, ESC, or clicking the
XXwindows close gadget.  Long listing can usually be aborted (without
XXaborting the program) by pressing CTRL-K.  Pressing CTRL-S or the
XX'spacebar' will generally pause long listings.  Pressing CTRL-Q or the
XX'spacebar' again, will generally restart the listing (such as when
XXlisting memory locations).  I urge any programmers who modify this
XXprogram, to keep these things rather constant (ie.  CTRL-K should always
XXabort long listings especially).  Looking through the source code should
XXinform you how.  And yes, I urge programmers to add to/modify/improve
XXthe program, ESPECIALLY in the user interface department (allthough I
XXhave made CONSIDERABLE improvements in this area). 
XX
XX	I am including the original source which I used to port the
XXprogram.  It should always be available in unaltered form for reference. 
XXIt is called "CoreOLD.c".  Please include it with any modified
XXsources/programs that you release, unless it is readily available
XXelsewhere.  This is so that people can see where any modifications to
XXthe original were made, and also so that if anyone criticizes the
XX"soundness" of my source code, I can prove that I indeed got it that
XXway.
XX	If you want to add any information about any modifications you
XXmake to the program, just append your information to the end of this
XXfile (or to the beginning, or to the...)
XX
XX
XX
XX	I am also including two example programs in this package, IMP
XXand DWARF, which should demonstrate how to get started in writing
XX"Redcode" programs.
XX
XX	For any comments, I can be reached on USENET at:
XX		portal!cup.portal.com.!Chad_The-Walrus_Netzer
XX	(or somewhere along that route...)
XX
XX				** OR **
XX
XX	On BBS-JC (Mountain View, Ca.) at:
XX		(415)-961-7250
XX	as "Chad Netzer"
XX
XX				** OR **
XX
XX	Contact me at:
XX		1115 Highlands Circle
XX		Los Altos, Ca.   94022
XX		(415)-961-0156
XX
XX
XX	I can't think of anything else to mention, so I'm signing off...
XX	<Log Off ... 02/29/88>
XX
XX
XX	"I am he, as you are he, as you are me, and we are all together!"
SHAR_EOF
if test 3241 -ne "`wc -c README.1st`"
then
echo shar: error transmitting README.1st '(should have been 3241 characters)'
fi
echo shar: extracting IMP
sed 's/^XX//' << \SHAR_EOF > IMP
XXmov 0 1
SHAR_EOF
if test 8 -ne "`wc -c IMP`"
then
echo shar: error transmitting IMP '(should have been 8 characters)'
fi
echo shar: extracting DWARF
sed 's/^XX//' << \SHAR_EOF > DWARF
XXDAT	-1
XXADD	#5	-1
XXMOV	#0	@-2
XXJMP	-2
XX
SHAR_EOF
if test 36 -ne "`wc -c DWARF`"
then
echo shar: error transmitting DWARF '(should have been 36 characters)'
fi
echo shar: extracting corewar.c
sed 's/^XX//' << \SHAR_EOF > corewar.c
XX
XX
XX/*	COREWARS 2.C	The game of Core Wars, as described by
XX**			A.K. Dewdney in the May 1984 issue of
XX**			Scientific American. 
XX**
XX**			Note: Output redirection will effect detailed
XX**			      listings ONLY! (And it'll probably be a
XX**			      BIG file.)
XX**
XX**	Date: 28 May 1984
XX**	Author: Kevin A. Bjorke
XX**
XX**	Copyright (C) 1984 Kevin A. Bjorke
XX**	Released to the Public Domain for Non-Commercial Use Only
XX**
XX**      7-June-1984 Bob Green
XX**          Converted to MS-DOS 2.xx   -  Computer Innovations  C86
XX**          and A TeleVideo 950 terminal from CP/M and Small-C 2.03  
XX**
XX**	28-February-1988 	Chad The_Walrus Netzer
XX**
XX**		Ported the above version to the Amiga computer.  Used
XX**	Manx Aztec C version 3.4a to develop and compile.  This is
XX**	a "no frills" version.  This version is freely redistributable,
XX**	but not for commercial use.  Feel free to add/modify/improve it.
XX**	In fact, I'm sure there are parts of the user interface you'll want
XX**	to improve.  If so, DO so!!!  And then release it for everyone else's
XX**	pleasure.  Please include all source code with ANY executable you
XX**	distribute!  Others will thank you, and so will I.
XX**		PS.  Sorry, for the messy code, in places, but that's what
XX**	comes from porting...  I didn't bother keeping track of my code,
XX**	and the old code.  So have fun figuring it out! (I did.)
XX** 
XX**		I intend to add to this program in my spare-spare time...
XX**	But don't wait for me to do all the work.  This program could
XX**	use a couple notable additions (better command line editing,
XX**	I/O redirection, comments in program listings, support for unattended
XX**	'tournament' play, and better listing of memory comes to mind).  Hope 
XX**	you enjoy fiddling with it.  You can contact me on Usenet at:
XX**
XX**		portal!cup.portal.com!Chad_The-Walrus_Netzer (I think).
XX**	Look for me in the comp.sys.amiga section.  Or call BBS-JC at:
XX**
XX**		415-961-7250	(Mountain View, Ca.)
XX**	and look for Chad Netzer on the board...
XX**
XX*/
XX
XX#include "stdio.h"
XX#include "sgtty.h"
XX
XX#include "corewar.h"	/* header file for Amiga IO routines */
XX
XX#define MAXSIZE 1000		/* Dewdney has 8000 - change to your taste */
XX#define VERSION "1.01"
XX#define CLRSCR "\033*"		/* For Telcon, Heath, Etc. */
XX#define ADRCUR "\033="		/* Likewise */
XX#define BIAS 31			/* Ditto */
XX#define INDEXED 2		/* Modes (Indexed = Indirect) */
XX#define DIRECT 1
XX#define IMMEDIATE 0
XX#define CUTOFF 2000		/* Max. number of instructions executed */
XX#define BLANK ' '
XX#define CR 0x0d
XX#define LF 0x0a
XX#define ENQ 0xB
XX#define FULLIST 		/* List what's going where on MOV, ADD, etc */
XX
XX#define ERROR	-1
XX#define BELL	0x7
XX
XXvoid	querymem();
XX
XX/*
XX**********************
XX** Global Variables **
XX
XX**********************
XX*/
XX
XXchar proga[80];			/* names of the battle programs */
XXchar progb[80];
XX
XXint pc[2];			/* Redcode program counters */
XXchar instr;			/* Current instruction */
XXint modea, modeb;		/* Current addressing modes -- see below */
XXint now;			/* programs 0 and 1 (pc index) */
XXchar line[12];			/* large enough to accept anything required */
XXchar show;			/* used to differentiate between showing and */
XX				/* executing code */
XX
XXchar code[MAXSIZE];		/* Redcode Instructions */
XXint  arga[MAXSIZE];		/* Battle Prog Arguments */
XXint  argb[MAXSIZE];		/* Total: 5 bytes per "location" */
XX
XX
XX/*
XX** Since the Redcode Instruction set has only 9 instruction and 3 addressing
XX** modes, the code is split into three fields:
XX**
XX**	Bit:	7 6 5 4 3 2 1 0
XX**		a a b b i i i i
XX**
XX** where a = mode of argument a
XX**       b = mode of argument b
XX**       i = instruction (0-8 -- 9-15 treated as 0, or invalid)
XX**
XX** modes: 0 - immediate
XX**        1 - direct
XX**        2 - indirect
XX*/
XX
XX/*
XX*************************
XX** Main Program Driver **
XX*************************
XX*/
XX
XXmain()	
XX{
XX	while (TRUE) {
XX		mysetup();
XX		logo();
XX		clean();
XX		prepare();
XX		fight();
XX		querymem();
XX		myputs("\n\nPlay Again (Y/N) ? ");
XX		if (toupper(mygetc()) != 'Y')
XX			break;
XX	}
XX	puts("\n\n    Thththththat\'s all, folks....\n");
XX	myexit(0);
XX}
XX
XX/*
XX** Advertise the program
XX*/
XXlogo()
XX{
XX	myputs("^[c");
XX	myputs("\n\n    ****************************************\n");
XX	myputs("    **                                    **\n");
XX	myputs("    **         C O R E    W A R S         **\n");
XX	myputs("    **                                    **\n");
XX	myputs("    ****************************************\n\n\n");
XX	myputs("    MARS Version ");
XX	myputs(VERSION);
XX	myputs("   Kevin Bjorke 5/28/84\n\n");
XX}
XX
XX/*
XX********************
XX** Input Routines **
XX********************
XX*/
XX
XX/*
XX** Read in both programs
XX*/
XXprepare()
XX{
XX	int top,bot;
XX	char *p;
XX	FILE *fp1,*fp2;			/* possible file pointer */
XX
XX	myputs("\n    Enter the name of Battle-Program A: ");
XX	mygets(proga,80);
XX	myputs("\n    Enter the name of Battle-Program B: ");
XX	mygets(progb,80);
XX	for (p = &progb[0]; *p; ++p)
XX		*p = toupper(*p);
XX	for (p = &proga[0]; *p; ++p)
XX		*p = toupper(*p);
XX	bot = 0;
XX	bot = getinitial(proga,bot);	/* find out where to initially put the program */
XX	if ((fp1 = fopen(proga,"r")) == NULL) {
XX		myputs("^[c");
XX		myputs("\n\nPlease enter code for ");
XX		myputs(proga);
XX		myputs(":\n\n");
XX		top = getprog(proga,bot);
XX	} else
XX		top = fgetprog(fp1,bot);
XX	myprintf("\nNow listing Program %s:\n\n",proga);
XX	showmem(bot,top);
XX	pc[0] = bot;
XX	getpc(0);
XX	bot = MAXSIZE/2;
XX	bot = getinitial(progb,bot);	/* find out where to initially put the program */
XX	if (ABS(bot - pc[0]) < MAXSIZE/8)  {
XX		bot = pc[0] + MAXSIZE/8;
XX		bot = reladr(bot,0);
XX		myputs("I have to re-adjust your starting position!\n");
XX		myprintf("Your new location is %d.",bot); 
XX	}
XX	if ((fp2 = fopen(progb,"r")) == NULL) {
XX		myputs("^[c");
XX		myputs("\n\nNow, please enter code for ");
XX		myputs(progb);
XX		myputs(":\n\n");
XX		top = getprog(progb,bot);
XX	} else
XX		top = fgetprog(fp2,bot);
XX	myprintf("\nNow listing Program %s:\n\n",progb);
XX	showmem(bot,top);
XX	pc[1] = bot;
XX	getpc(1);
XX}
XX
XX/*
XX** get a program from the keyboard
XX*/
XXgetprog(prg,ct) char *prg; int ct;
XX{
XX	int i,row; 
XX        char *pt;
XX	row = 10;
XX	myputs("Enter program one line at a time.\n");
XX	myputs("Pressing RETURN between arguments.\n");
XX	myputs("    Use END to finish\n\n");
XX	header(9);
XX	while (TRUE) {
XX		modea = modeb = DIRECT;
XX		cursor(row,1);
XX		stout(ct);
XX		cursor(row,10);
XX		mygets(line,12);
XX		for (i = 0; line[i]; ++i) {
XX			if (('\n' == line[i]) || ('\t' == line[i]) || (' ' == line[i]))
XX				line[i] = '\0';
XX			line[i] = toupper(line[i]);
XX		}
XX		if ((i = getinst(ct)) == NULL)
XX			break;
XX		if (i == ERROR) {
XX 			cursor(row,10);
XX			myputs("\007???\n");
XX			continue;
XX		}
XX		cursor(row,50);
XX		myputs(line);
XX		if (code[ct] != 0) {
XX			cursor(row,20);
XX			mygets(line,12);
XX			pt = &line[0];
XX			cursor(row,60);
XX			if (*pt == '@') {
XX				myputs("Indirect");
XX				modea = INDEXED;
XX				++pt;
XX			} else if (*pt == '#') {
XX				myputs("Immediate");
XX				modea = IMMEDIATE;
XX				++pt;
XX			}  else
XX				myputs("Direct");
XX			i = stoi(pt);
XX			arga[ct] = i;
XX		}
XX		if (code[ct] != 4) {
XX			cursor(row,30);
XX			mygets(line,12);
XX			pt = &line[0];
XX			cursor(row,70);
XX			if (*pt == '@') {
XX				myputs("Indirect");
XX				modeb = INDEXED;
XX				++pt;
XX			} else if (*pt == '#') {
XX				myputs("Immediate");
XX				modeb = IMMEDIATE;
XX				++pt;
XX			} else
XX				myputs("Direct");
XX			i = stoi(pt);
XX			argb[ct] = i;
XX		}
XX		modea *= 64;
XX		modea &= 192;
XX		modeb *= 16;
XX		modeb &= 48;
XX		code[ct] += (modea + modeb);
XX		++ct;
XX		if ((++row) > 23) {
XX			row = 2;
XX			myputs("^[c");
XX			header(1);
XX		}
XX	}
XX	myputs("\n    Code for ");
XX	myputs(prg);
XX	myputs(" completed.\n");
XX	return(ct);
XX}
XX
XX/*
XX** get a program from a file
XX*/
XXfgetprog(prg,ct)
XX FILE	*prg;
XX int	ct;
XX{
XX	int i; char *pt;
XX	myputs("\nNow reading program file...\n\n");
XX	while (TRUE) {
XX		modea = modeb = DIRECT;
XX		if (nextword(prg) == FALSE)
XX			break;
XX		if ((i = getinst(ct)) == NULL)
XX			break;
XX		if (i == ERROR) {
XX			myputs("\007\nError - file fouled up!!!\n");
XX			myexit(0);
XX		}
XX		if (code[ct] != 0) {
XX			nextword(prg);
XX			arga[ct] = rdarg(&modea);
XX		}
XX		if (code[ct] != 4) {
XX			nextword(prg);
XX			argb[ct] = rdarg(&modeb);
XX		}
XX		modea *= 64;
XX		modea &= 192;
XX		modeb *= 16;
XX		modeb &= 48;
XX		code[ct] += (modea + modeb);
XX		++ct;
XX	}
XX	fclose(prg);
XX	return(ct);
XX}
XX
XX/*
XX** select an instruction from the vaule in line[]
XX*/
XXgetinst(indx)
XXint indx;
XX{
XX	if (strcmp(line,"MOV") == NULL)
XX		code[indx] = 1;
XX	else if (strcmp(line,"ADD") == NULL)
XX		code[indx] = 2;
XX	else if (strcmp(line,"SUB") == NULL)
XX		code[indx] = 3;
XX	else if (strcmp(line,"JMP") == NULL)
XX		code[indx] = 4;
XX	else if (strcmp(line,"JMZ") == NULL)
XX		code[indx] = 5;
XX	else if (strcmp(line,"JMG") == NULL)
XX		code[indx] = 6;
XX	else if (strcmp(line,"DJZ") == NULL)
XX		code[indx] = 7;
XX	else if (strcmp(line,"CMP") == NULL)
XX		code[indx] = 8;
XX	else if (strcmp(line,"DAT") == NULL)
XX		code[indx] = 0;
XX	else if (strcmp(line,"END") == NULL)
XX		return(NULL);
XX	else 
XX		return(ERROR);
XX	return(TRUE);
XX}
XX
XX/*
XX** get an argument value from line[]
XX*/
XXrdarg(md) char *md;
XX{
XX	char *pt; int i;
XX	pt = &line[0];
XX	if (*pt == '@') {
XX		*md = INDEXED;
XX		++pt;
XX	} else if (*pt == '#') {
XX		*md = IMMEDIATE;
XX		++pt;
XX	}
XX	i = stoi(pt);
XX	return(i);
XX}
XX
XX/*
XX** set the program counters to their initial locations
XX*/
XXgetpc(i)
XXint i;
XX{
XX	myprintf("\nStart execution at what location (default = %d )?: ",pc[i]);
XX	mygets(line,12);
XX	if (line[0] == '\0')	/* set to default if no input */
XX		return;
XX	pc[i] = stoi(line);
XX	pc[i] = reladr(pc[i],0);
XX}
XX
XX/*
XX** print programming header on screen
XX*/
XXheader(rw)
XXint rw;
XX{
XX	cursor(rw,1);
XX	myputs("Addr");
XX	cursor(rw,10);
XX	myputs("Instr");
XX	cursor(rw,20);
XX	myputc('A');
XX	cursor(rw,30);
XX	myputc('B');
XX	cursor(rw,55);
XX	myputs("Modes:");
XX}
XX
XX/*
XX** Get the next word from a TEXTfile, making sure to capitalize
XX*/
XXnextword(fil)
XXFILE *fil;
XX{
XX	char *pt, c;
XX	pt = &line[0];
XX	c = '\t';
XX	while ((c == '\t') || (c == BLANK) || (c == CR) || (c == LF)) {
XX		if ((c = toupper(getc(fil))) == EOF)
XX			return (FALSE);
XX	}
XX	while ((c != '\t') && (c != BLANK) && (c != CR) && (c != LF)) {
XX		*pt++ = c;
XX		if ((c = toupper(getc(fil))) == EOF)
XX			return (FALSE);
XX	}
XX	*pt++ = '\0';
XX	return(TRUE);
XX}
XX
XX
XX
XX/*
XX** Show memory
XX*/
XXshowmem(start,finish)
XXint start, finish;
XX{
XX	int ct,c;
XX	myprintf("Addresses %4d through %4d.\n",start,(finish-1));
XX	show = TRUE;
XX	myputc('\n');
XX	for (ct = start; ct < finish; ++ct) {
XX		readloc(ct);
XX		myputc('\n');
XX		if((c = mygetchar()) == EOF)
XX			myexit(0);
XX		if((c & 0x7f) == ENQ)
XX			break; 
XX	}
XX}
XX	
XX/*
XX****************************
XX** MASTER BATTLE ROUTINES **
XX****************************
XX*/
XX
XX/*
XX** Fight it out
XX*/
XXfight()
XX{
XX	int ct, i;
XX	show = FALSE;
XX	myputs("^[c");
XX	myputs("    PRESS ANY KEY TO BEGIN ");
XX	mygetc();	/* wait for a keypress */
XX	myputs("\n\nBeginning Battle...\n\n");
XX	myputs("    > ^K to Abort <\n\n");
XX	myprintf("\t%8s\t\t\t%8s\n\n",proga,progb);
XX	for (ct = 0; ct < CUTOFF; ++ct) {
XX		if ((ct % 5) == 0)
XX			myputc('\n');
XX		stout(ct);
XX		now = 0;
XX		if (readloc(pc[0]) == NULL)
XX			break;
XX		myputs("    ");
XX		now = 1;
XX		if (readloc(pc[1]) == NULL)
XX			break;
XX		myputc('\n');
XX		if ((mygetchar() & 0x7f) == ENQ)
XX			break;
XX		for (i = 0; i <2; ++i)
XX			pc[i] = reladr(pc[i],0);
XX	}
XX	myputc(BELL);
XX	myprintf("\nBattle Completed after %d instruction cycles!\n",ct);
XX	if (ct == CUTOFF)
XX		myputs("\>Draw<\n");
XX}	
XX
XX/*
XX** read a location, print the mnemonic, and perform it
XX*/
XXreadloc(loc)
XXint loc;
XX{
XX	char ma, mb; int res;
XX	instr = modea = modeb = code[loc];
XX	instr &= 15;		/* or 0x0F */
XX	modea = (modea / 64) & 3;
XX	modeb = (modeb / 16) & 3;
XX	res = -1;
XX	if (instr == 1)			/* can't use switch with char arg */
XX		mov();
XX	else if (instr == 2)
XX		add();
XX	else if (instr == 3)
XX		sub();
XX	else if (instr == 4)
XX		jmp();
XX	else if (instr == 5)
XX		jmz();
XX	else if (instr == 6)
XX		jmg();
XX	else if (instr == 7)
XX		djz();
XX	else if (instr == 8)
XX		cmp();
XX	else {
XX		myputs("DAT");
XX		res = NULL;
XX	}
XX	myprintf("    %c%3d    %c%3d [%3d]",mnem(modea),arga[loc],mnem(modeb),argb[loc],loc);
XX	return(res);
XX}
XX
XX/*
XX*********************************************
XX** functions to perform Redcode operations **
XX*********************************************
XX*/
XX
XX/*
XX** Redcode MOV instruction
XX*/
XXmov()
XX{
XX	int a,b;
XX	myputs("MOV");
XX	if (show)
XX		return(NULL);
XX	b = findadr(pc[now], &argb[0], modeb);
XX	if (modea == IMMEDIATE) {
XX		code[b] = 0;			/* make it a DAT */
XX		argb[b] = arga[pc[now]];
XX#ifdef FULLIST
XX		myprintf("|#%6d>%3d|",arga[pc[now]],b);
XX#endif
XX	} else {
XX		a = findadr(pc[now], &arga[0], modea);
XX#ifdef FULLIST
XX		myprintf("|%3d>%3d|",a,b);
XX#endif
XX		code[b] = code[a];
XX		arga[b] = arga[a];
XXargb[b] = argb[a];
XX	}
XX	++pc[now];
XX}
XX
XX/*
XX** Redcode ADD instruction
XX*/
XXadd()
XX{
XX	int a,b;
XX	myputs("ADD");
XX	if (show)
XX		return(NULL);
XX	b = findadr(pc[now], &argb[0], modeb);
XX	if (modea == IMMEDIATE) {
XX		argb[b] += arga[pc[now]];
XX#ifdef FULLIST
XX		myprintf("|#%6d+%3d|",arga[pc[now]],b);
XX#endif
XX	} else {
XX		a = findadr(pc[now], &arga[0], modea);
XX#ifdef FULLIST
XX		myprintf("|%3d+%3d|",b,a);
XX#endif
XX		argb[b] += arga[a];
XX	}
XX	++pc[now];
XX}
XX
XX/*
XX** Redcode SUB instruction
XX*/
XXsub()
XX{
XX	int a,b;
XX	myputs("SUB");
XX	if (show)
XX		return(NULL);
XX	b = findadr(pc[now], &argb[0], modeb);
XX	if (modea == IMMEDIATE) {
XX		argb[b] -= arga[pc[now]];
XX#ifdef FULLIST
XX		myprintf("|%3d-#%6d|",b,arga[pc[now]]);
XX#endif
XX	} else {
XX		a = findadr(pc[now], &arga[0],modea);
XX#ifdef FULLIST
XX		myprintf("|%3d-%3d|",b,a);
XX#endif
XX		argb[b] -= arga[a];
XX	}
XX	++pc[now];
XX}
XX
XX/*
XX** Redcode JMP Instruction
XX*/
XXjmp()
XX{
XX	int a;
XX	myputs("JMP");
XX	if (show)
XX		return(NULL);
XX	pc[now] = findadr(pc[now], &arga[0], modea);
XX}
XX
XX/*
XX** Redcode JMZ instruction
XX*/
XXjmz()
XX{
XX	int b;
XX	myputs("JMZ");
XX	if (show)
XX		return(NULL);
XX	b = findadr(pc[now], &argb[0], modeb);
XX#ifdef FULLIST
XX	myprintf("|%3d|",b);
XX#endif
XX	if (argb[b] == 0)
XX		pc[now] = findadr(pc[now], &arga[0], modea);
XX	else
XX		++pc[now];
XX}
XX
XX
XX/*
XX** Redcode JMG Instruction
XX*/
XXjmg()
XX{
XX	int b;
XX	myputs("JMG");
XX	if (show)
XX		return(NULL);
XX	b = findadr(pc[now], &argb[0], modeb);
XX#ifdef FULLIST
XX	myprintf("|%3d|",b);
XX#endif
XX	if (argb[b] != 0)
XX		pc[now] = findadr(pc[now], &arga[0], modea);
XX	else
XX		++pc[now];
XX}
XX	
XX/*
XX** Redcode DJZ Instruction
XX*/
XXdjz()
XX{
XX	int b;
XX	myputs("DJZ");
XX	if (show)
XX		return(NULL);
XX	b = findadr(pc[now], &argb[0], modeb);
XX#ifdef FULLIST
XX	myprintf("|%3d|",b);
XX#endif
XX	if ((--argb[b]) == NULL)
XX		pc[now] = findadr(pc[now], &arga[0], modea);
XX	else
XX		++pc[now];
XX}
XX
XX/*
XX** Redcode CMP Instruction
XX*/
XXcmp()
XX{
XX	int a,b;
XX	myputs("CMP");
XX	if (show)
XX		return(NULL);
XX	if (modea != IMMEDIATE) {
XX		a = findadr(pc[now], &arga[0], modea);
XX		a = argb[a];
XX	} else
XX		a = arga[pc[now]];
XX	if (modeb != IMMEDIATE) {
XX		b = findadr(pc[now], &argb[0], modeb);
XX		b = argb[b];
XX	} else
XX		b = argb[pc[now]];
XX	++pc[now];
XX	if (a != b)
XX		++pc[now];
XX}
XX
XX/*
XX*************************
XX** Addressing Routines **
XX*************************
XX*/
XX
XX/*
XX** find an address via direct or indirect
XX*/
XXfindadr(orig,pab,mod) int orig, *pab; char mod;
XX{
XX	int p;
XX	if (mod == IMMEDIATE)
XX		return(orig);
XX	p = reladr(orig,pab[orig]);
XX	if (mod == INDEXED)
XX		p = reladr(p,argb[p]);
XX	return(p);
XX}
XX
XX
XX/*
XX** return an absolute address in the circular arena from a relative one
XX*/
XXreladr(abs,rel) int abs,rel;
XX{
XX	int j;
XX	if ((j = abs + rel) >= MAXSIZE)
XX		j = reladr((j - MAXSIZE),0);
XX	else if (j < 0)
XX		j = reladr((j + MAXSIZE),0);
XX	return(j);
XX}
XX
XX/*
XX****************************
XX** Miscellaneous routines **
XX****************************
XX*/
XX
XX/*
XX** Start with a "clean slate" in the battle-code arena
XX*/
XXclean()
XX{
XX	int i;
XX	for (i = 0; i < MAXSIZE; ++i) {
XX		code[i] = '\0';
XX		arga[i] = NULL;
XX		argb[i] = NULL;
XX	}
XX}
XX
XX/*
XX** return appropriate character for addressing modes
XX*/
XXmnem(c) char c;
XX{
XX	c &= 255;
XX	if (c == IMMEDIATE)
XX		return('#');
XX	else if (c == INDEXED)
XX		return('@');
XX	else
XX		return('.');
XX}
XX
XX/*
XX** return an integer from a string
XX*/
XXstoi(str) char *str;
XX{
XX	int i,s;
XX	if (*str == '-') {
XX		s = -1;
XX		++str;
XX	} else
XX		s = 1;
XX	i = 0;
XX	while ((*str >= '0') && (*str <= '9'))
XX		i = (10 * i) + (*str++ - '0');
XX	i *= s;
XX	return (i);
XX}
XX
XX/*
XX** print a string to stderr from an integer <= 9999
XX*/
XXstout(i) int i;
XX{
XX	if (i < 0)
XX		myputc('-');
XX	myputc((i / 1000 + '0'));
XX	i %= 1000;
XX	myputc((i / 100 + '0'));
XX	i %= 100;
XX	myputc((i / 10 + '0'));
XX	i %= 10;
XX	myputc((i + '0'));
XX	myputs(":  ");
XX}
XX
XX/*
XX** Address the cursor (Currently set for Heath/Telcon)
XX*/
XXcursor(row,col)
XXint row,col;
XX{
XX	myprintf("^[[%d;%dH", row, col);
XX}
XX
XX/* prompts user to specify where program should be located in memory */
XXgetinitial(progname,start)
XXchar	progname[];
XXint	start;
XX{
XX	char buffer[12];
XX	int i;
XX
XX	myprintf("\n\nWhere should the program called (%s) be located (default = %d )?:  ",progname,start);
XX	mygets(buffer,12);
XX	if (buffer[0] == '\0') {	/* set to default if no input */
XX		i = start;
XX		i = reladr(i,0);
XX		return(i);
XX	}
XX	i = stoi(buffer);
XX	i = reladr(i,0);
XX	return(i);
XX}
XX
XXvoid querymem()
XX{
XX	int start,end;
XX	char buffer[12];
XX
XX	while(1){
XX		myputs("\nList Memory? ");
XX		if (toupper(mygetc()) != 'Y')
XX			break;
XX		myputs("\n\nEnter starting address to display (default = 0): ");
XX		mygets(buffer,12);
XX		if (buffer[0] == '\0')	/* set to default if no input */
XX			start = 0;
XX		else {
XX			start = stoi(buffer);
XX			start = reladr(start,0);
XX		}
XX		myputs("\n\nEnter ending address to display (default = MAXSIZE): ");
XX		mygets(buffer,12);
XX		if (buffer[0] == '\0')	/* set to default if no input */
XX			end = MAXSIZE;
XX		else {
XX			end = stoi(buffer);
XX			end = reladr(end,0);
XX			if (start > end) {
XX				myputs("\nStart address has to be smaller than ending address\n");
XX				continue;
XX			}
XX		}
XX		showmem(start,end);
XX	}
XX}
XX
XX/* end of CORE WARS 2 */
SHAR_EOF
if test 17261 -ne "`wc -c corewar.c`"
then
echo shar: error transmitting corewar.c '(should have been 17261 characters)'
fi
echo shar: extracting corewar.h
sed 's/^XX//' << \SHAR_EOF > corewar.h
XX/*  contains I/O information for use with the Amiga */
XX
XX/* most of the code is borrowed from some John Toebes source */
XX
XX
XX#include <libraries/dos.h>
XX#include <intuition/intuition.h>
XX#include <exec/exec.h>
XX#include <exec/io.h>
XX#include <exec/ports.h>
XX#include <exec/types.h>
XX#include <clib/macros.h>
XX#include "ctype.h"
XX#include "functions.h"
XX
XX#define EOF	-1
XX#define	BACKSPACE 0x8
XX#define GRAPHICS_REV	29L
XX#define INTUITION_REV	29L
XX
XXvoid myexit();
XXchar *mygets();
XX
XXstruct IntuitionBase *IntuitionBase;
XXstruct GfxBase *GfxBase;
XX
XXstatic struct IOStdReq conrequest;
XXstruct Window *unixwindow;
XX
XX
XX/* window of operations */
XXstatic struct NewWindow NewWindow = {
XX	0, 1, 640, 199, -1, -1,
XX	CLOSEWINDOW | VANILLAKEY,
XX	WINDOWDEPTH | WINDOWDRAG | WINDOWCLOSE | ACTIVATE | WINDOWSIZING
XX	| SIZEBBOTTOM | SMART_REFRESH | NOCAREREFRESH,
XX	NULL, NULL,
XX	(UBYTE *)"Amiga CoreWars 1.01w -- Ported by Chad 'The_Walrus' Netzer  02/28/88",
XX/* The "w" indicates it's my (The_Walrus's) version.  You can adopt a similar scheme (with a different letter or symbol) */
XX	NULL, NULL, 60, 20, -1, -1, WBENCHSCREEN };
XX	
XX/* Initialize the window so we can read and write to it */
XXvoid mysetup()
XX{
XX	/* If we haven't already initialized, then do so now */
XX	if (unixwindow == NULL) {
XX		/* Open up the libraries we will need to use */
XX		if ((IntuitionBase = (struct IntuitionBase *)
XX			OpenLibrary("intuition.library",INTUITION_REV)) == NULL) {
XX			puts("Oh shit!  I can't open Intuition!!");
XX			_exit(1);
XX		}
XX		
XX		if ((GfxBase = (struct GfxBase *)
XX			OpenLibrary("graphics.library",GRAPHICS_REV)) == NULL) {
XX			puts("Oh crap!  I can't do any graphics!");
XX			_exit(2);
XX		}
XX			
XX		/* Open up the window on the Workbench screen */
XX		if ((unixwindow = (struct Window *)OpenWindow(&NewWindow)) == NULL) {
XX			puts("Fucken A!  The damn window won't open!!");
XX			_exit(3);
XX		}
XX			
XX		/* And attach a console.device to it for output */
XX		conrequest.io_Data = (APTR)unixwindow;
XX		conrequest.io_Length = sizeof(*unixwindow);
XX		if(OpenDevice("console.device",0L,(struct IORequest *)&conrequest,0)) {
XX			puts("By Gosh, you're console.device won't open.");
XX			myexit(6);
XX		}
XX	}
XX	return;
XX}
XX
XXint mygetc() /* read a character from our special window (wait if no event) */
XX{
XX	register int c;
XX	struct IntuiMessage *Message;
XX	
XX	if(unixwindow == NULL)
XX		mysetup();	/* make sure we are initialized */
XX		
XX	/* wait until something happens */
XX	while((Message = (struct IntuiMessage *)GetMsg(unixwindow->UserPort)) == NULL)
XX		Wait(1L<<unixwindow->UserPort->mp_SigBit);
XX
XX	switch(Message->Class)
XX	{
XX		case CLOSEWINDOW:
XX			c = EOF;
XX			break;
XX			
XX		case VANILLAKEY:
XX			if((c = Message->Code)== 0x1c)  /* CTRL - \ */
XX				c = EOF;
XX			else if (c == 0x03)		/* CTRL - C */
XX				c = EOF;
XX			else if (c == 0x1B)		/* ESC key */
XX				c = EOF;
XX			else if(c == 0x0d)		/* carriage return */
XX				c = '\n';
XX			break;		/* just a key, nothing special */
XX			
XX		default:
XX			c = EOF;
XX			break;
XX	}
XX	ReplyMsg((struct Message *)Message);
XX	if (EOF==c) {
XX		myexit(0);
XX	}
XX	return(c);
XX}
XX
XX
XXint mygetchar() /* read a character from our special window (don't wait if no event) */
XX{
XX	register int c;
XX	struct IntuiMessage *Message;
XX	
XX	if(unixwindow == NULL)
XX		mysetup();	/* make sure we are initialized */
XX		
XX	while((Message = (struct IntuiMessage *)GetMsg(unixwindow->UserPort)) == NULL)
XX 		return(NULL);
XX
XX	switch(Message->Class)
XX	{
XX		case CLOSEWINDOW:
XX			c = EOF;
XX			break;
XX			
XX		case VANILLAKEY:
XX			if((c = Message->Code)== 0x1c)  /* CTRL - \ */
XX				c = EOF;
XX			else if (c == 0x03)		/* CTRL - C */
XX				c = EOF;
XX			else if (c == 0x1B)		/* ESC key */
XX				c = EOF;
XX			else if(c == 0x0d)		/* carriage return */
XX				c = '\n';
XX			else if(c == 0x13 || c == ' ')  /* Pause on CTRL-S or SPACE */
XX				while(!((c = mygetc()) == 0x11 || (c == ' ')))
XX					;	/* CTRL-Q or SPACE to restart */
XX			break;
XX			
XX		default:
XX			c = EOF;
XX			break;
XX	}
XX	ReplyMsg((struct Message *)Message);
XX	if (EOF==c) {
XX		myexit(0);
XX	}
XX	return(c);
XX}
XX
XXvoid	myputc(c)
XXchar c;
XX{
XX	
XX	if(unixwindow == NULL)
XX		mysetup();	/* make sure we are initialized */
XX
XX	conrequest.io_Command = CMD_WRITE;
XX	conrequest.io_Data = (APTR)&c;
XX	conrequest.io_Length = 1;
XX	/* send write request to console.device */
XX	DoIO((struct IORequest *)&conrequest);
XX}
XX
XXvoid myputs(str)	/* write a string to our window */
XXchar *str;
XX{
XX	if(unixwindow == NULL)
XX		mysetup();	/* make sure we are initialized */
XX	
XX	conrequest.io_Command = CMD_WRITE;
XX	conrequest.io_Data = (APTR)str;
XX	conrequest.io_Length = strlen(str);
XX	DoIO((struct IORequest *)&conrequest);
XX}	
XX
XX/* write a formatted string to our window */
XXvoid myprintf(str, v1, v2, v3, v4, v5, v6, v7, v8, v9)
XXchar *str;
XXlong v1, v2, v3, v4, v5, v6, v7, v8, v9;
XX{
XX	char buff[256];
XX	
XX	if(unixwindow == NULL)
XX		mysetup();	/* make sure we are initialized */
XX
XX	conrequest.io_Length = sprintf(buff,str,v1,v2,v3,v4,v5,v6,v7,v8,v9);
XX	conrequest.io_Command = CMD_WRITE;
XX	conrequest.io_Data = (APTR)buff;
XX	DoIO((struct IORequest *)&conrequest);
XX}
XX
XXchar 	*mygets(buffer, length)
XXchar	buffer[];
XXint	length;
XX{
XX	int count;
XX	for (count = 0; count < length; count++) {
XX		do {
XX			buffer[count] = (char)mygetc();
XX			if (buffer[count] == EOF)
XX				return(NULL);
XX		}
XX		while (!isascii(buffer[count])); /* skip over GARbage characters */
XX		myputc(buffer[count]);
XX
XX		if ('\n' == buffer[count])  {
XX			buffer[count] = '\0';
XX			return(&buffer[0]);
XX		}
XX
XX	/* could add better line editing/stripping here */
XX		if (BACKSPACE == buffer[count])	/* allow for backspace deleting */
XX			count = count - 2;
XX	}
XX}
XX
XX
XX/* close up everything and leave the program */
XXvoid myexit(code)
XXint code;
XX{
XX	if(unixwindow != NULL) {
XX		/* shut down in the opposite order we came up */
XX		CloseDevice((struct IORequest *)&conrequest);
XX		CloseWindow(unixwindow);
XX		CloseLibrary((struct Library *)GfxBase);
XX		CloseLibrary((struct Library *)IntuitionBase);
XX		unixwindow = NULL;
XX	}
XX	_exit(code);
XX}
SHAR_EOF
if test 5813 -ne "`wc -c corewar.h`"
then
echo shar: error transmitting corewar.h '(should have been 5813 characters)'
fi
echo shar: extracting CoreOLD.c
sed 's/^XX//' << \SHAR_EOF > CoreOLD.c
XX
XX
XX/*	COREWARS 2.C	The game of Core Wars, as described by
XX**			A.K. Dewdney in the May 1984 issue of
XX**			Scientific American. 
XX**
XX**			Note: Output redirection will effect detailed
XX**			      listings ONLY! (And it'll probably be a
XX**			      BIG file.)
XX**
XX**	Date: 28 May 1984
XX**	Author: Kevin A. Bjorke
XX**
XX**	Copyright (C) 1984 Kevin A. Bjorke
XX**	Released to the Public Domain for Non-Commercial Use Only
XX**
XX**      7-June-1984 Bob Green
XX**          Converted to MS-DOS 2.xx   -  Computer Innovations  C86
XX**          and A TeleVideo 950 terminal from CP/M and Small-C 2.03  
XX**
XX*/
XX
XX#include "local.h"
XX
XX#define MAXSIZE 1000		/* Dewdney has 8000 - change to your taste */
XX#define VERSION "1.01"
XX#define CLRSCR "\033*"		/* For Telcon, Heath, Etc. */
XX#define ADRCUR "\033="		/* Likewise */
XX#define BIAS 31			/* Ditto */
XX#define INDEXED 2		/* Modes (Indexed = Indirect) */
XX#define DIRECT 1
XX#define IMMEDIATE 0
XX#define CUTOFF 2000		/* Max. number of instructions executed */
XX#define BLANK ' '
XX#define CR 0x0d
XX#define LF 0x0a
XX#define ENQ 0x05
XX#define FULLIST 		/* List what's going where on MOV, ADD, etc */
XX/*
XX**********************
XX** Global Variables **
XX
XX**********************
XX*/
XX
XXchar proga[80];			/* names of the battle programs */
XXchar progb[80];
XX
XXint pc[2];			/* Redcode program counters */
XXchar instr;			/* Current instruction */
XXint modea, modeb;		/* Current addressing modes -- see below */
XXint now;			/* programs 0 and 1 (pc index) */
XXchar line[12];			/* large enough to accept anything required */
XXchar show;			/* used to differentiate between showing and */
XX				/* executing code */
XX
XXchar code[MAXSIZE];		/* Redcode Instructions */
XXint  arga[MAXSIZE];		/* Battle Prog Arguments */
XXint  argb[MAXSIZE];		/* Total: 5 bytes per ""location" */
XX
XX/*
XX** Since the Redcode Instruction set has only 9 instruction and 3 addressing
XX** modes, the code is split into three fields:
XX**
XX**	Bit:	7 6 5 4 3 2 1 0
XX**		a a b b i i i i
XX**
XX** where a = mode of argument a
XX**       b = mode of argument b
XX**       i = instruction (0-8 -- 9-15 treated as 0, or invalid)
XX**
XX** modes: 0 - immediate
XX**        1 - direct
XX**        2 - indirect
XX*/
XX
XX/*
XX*************************
XX** Main Program Driver **
XX*************************
XX*/
XX
XXmain()	
XX{
XX	while (TRUE) {
XX		logo();
XX		clean();
XX		prepare();
XX		fight();
XX		fputs("\nList Memory? ",stderr);
XX		if (toupper(flgetc()) == 'Y')
XX			showmem(0,MAXSIZE);
XX		fputs("\n\nPlay Again (Y/N) ? ",stderr);
XX		if (toupper(flgetc()) != 'Y')
XX			break;
XX	}
XX	fputs("\n\n\tThththththat\'s all, folks....\n",stderr);
XX}
XX
XX/*
XX** Advertise the program
XX*/
XXlogo()
XX{
XX	fputs(CLRSCR,stderr);
XX	fputs("\n\n\t****************************************\n",stderr);
XX	fputs("\t**                                    **\n",stderr);
XX	fputs("\t**         C O R E    W A R S         **\n",stderr);
XX	fputs("\t**                                    **\n",stderr);
XX	fputs("\t****************************************\n\n\n",stderr);
XX	fputs("\tMARS Version ",stderr);
XX	fputs(VERSION,stderr);
XX	fputs("   Kevin Bjorke 5/28/84\n\n",stderr);
XX}
XX
XX/*
XX********************
XX** Input Routines **
XX********************
XX*/
XX
XX/*
XX** Read in both programs
XX*/
XXprepare()
XX{
XX	int top,bot; char *p;
XX	int fp;			/* possible file pointer */
XX	fputs("\n\tEnter the name of Battle-Program A: ",stderr);
XX	gets(proga,80,stdin);
XX	fputs("\n\tEnter the name of Battle-Program B: ",stderr);
XX	gets(progb,80,stdin);
XX	for (p = &progb[0]; *p; ++p)
XX		*p = toupper(*p);
XX	for (p = &proga[0]; *p; ++p)
XX		*p = toupper(*p);
XX	bot = 0;
XX	if ((fp = fopen(proga,"r")) == NULL) {
XX		fputs(CLRSCR,stderr);
XX		fputs("\n\nPlease enter code for ",stderr);
XX		fputs(proga,stderr);
XX		fputs(":\n\n",stderr);
XX		top = getprog(proga,bot);
XX	} else
XX		top = fgetprog(fp,bot);
XX	printf("\nNow listing Program %s:\n\n",proga);
XX	showmem(bot,top);
XX	pc[0] = bot;
XX	getpc(0);
XX	bot = MAXSIZE / 2;
XX	if ((fp = fopen(progb,"r")) == NULL) {
XX		fputs(CLRSCR,stderr);
XX		fputs("\n\nNow, please enter code for ",stderr);
XX		fputs(progb,stderr);
XX		fputs(":\n\n",stderr);
XX		top = getprog(progb,bot);
XX	} else
XX		top = fgetprog(fp,bot);
XX	printf("\nNow listing Program %s:\n\n",progb);
XX	showmem(bot,top);
XX	pc[1] = bot;
XX	getpc(1);
XX}
XX
XX/*
XX** get a program from the keyboard
XX*/
XXgetprog(prg,ct) char *prg; int ct;
XX{
XX	int i,row; 
XX        char *pt;
XX	row = 10;
XX	fputs("Enter program one line at a time.\n",stderr);
XX	fputs("Pressing RETURN between arguments.\n",stderr);
XX	fputs("\tUse END to finish\n\n",stderr);
XX	header(9);
XX	while (TRUE) {
XX		modea = modeb = DIRECT;
XX		cursor(row,1);
XX		stout(ct);
XX		cursor(row,10);
XX		gets(line,12,stdin);
XX		for (i = 0; line[i]; ++i) {
XX			if ((line[i] == '\t') || (line[i] == ' '))
XX				line[i] = '\0';
XX			line[i] = toupper(line[i]);
XX		}
XX		if ((i = getinst(ct)) == NULL)
XX			break;
XX		if (i == ERROR) {
XX			cursor(row,10);
XX			fputs("\007???\n",stderr);
XX			continue;
XX		}
XX		cursor(row,50);
XX		fputs(line,stderr);
XX		if (code[ct] != 0) {
XX			cursor(row,20);
XX			gets(line,12,stdin);
XX			pt = &line[0];
XX			cursor(row,60);
XX			if (*pt == '@') {
XX				fputs("Indirect",stderr);
XX				modea = INDEXED;
XX				++pt;
XX			} else if (*pt == '#') {
XX				fputs("Immediate",stderr);
XX				modea = IMMEDIATE;
XX				++pt;
XX			}  else
XX				fputs("Direct",stderr);
XX			i = stoi(pt);
XX			arga[ct] = i;
XX		}
XX		if (code[ct] != 4) {
XX			cursor(row,30);
XX			gets(line,12,stdin);
XX			pt = &line[0];
XX			cursor(row,70);
XX			if (*pt == '@') {
XX				fputs("Indirect",stderr);
XX				modeb = INDEXED;
XX				++pt;
XX			} else if (*pt == '#') {
XX				fputs("Immediate",stderr);
XX				modeb = IMMEDIATE;
XX				++pt;
XX			} else
XX				fputs("Direct",stderr);
XX			i = stoi(pt);
XX			argb[ct] = i;
XX		}
XX		modea *= 64;
XX		modea &= 192;
XX		modeb *= 16;
XX		modeb &= 48;
XX		code[ct] += (modea + modeb);
XX		++ct;
XX		if ((++row) > 23) {
XX			row = 2;
XX			fputs(CLRSCR,stderr);
XX			header(1);
XX		}
XX	}
XX	fputs("\n\tCode for ",stderr);
XX	fputs(prg,stderr);
XX	fputs(" completed.\n",stderr);
XX	return(ct);
XX}
XX
XX/*
XX** get a program from a file
XX*/
XXfgetprog(prg,ct) int prg,ct;
XX{
XX	int i; char *pt;
XX	fputs("\nNow reasding program file...\n\n",stderr);
XX	while (TRUE) {
XX		modea = modeb = DIRECT;
XX		if (nextword(prg) == FALSE)
XX			break;
XX		if ((i = getinst(ct)) == NULL)
XX			break;
XX		if (i == ERROR) {
XX			fputs("\007\nError - file fouled up!!!\n",stderr);
XX			exit();
XX		}
XX		if (code[ct] != 0) {
XX			nextword(prg);
XX			arga[ct] = rdarg(&modea);
XX		}
XX		if (code[ct] != 4) {
XX			nextword(prg);
XX			argb[ct] = rdarg(&modeb);
XX		}
XX		modea *= 64;
XX		modea &= 192;
XX		modeb *= 16;
XX		modeb &= 48;
XX		code[ct] += (modea + modeb);
XX		++ct;
XX	}
XX	fclose(prg);
XX	return(ct);
XX}
XX
XX/*
XX** select an instruction from the vaule in line[]
XX*/
XXgetinst(indx) int indx;
XX{
XX	if (strcmp(line,"MOV") == NULL)
XX		code[indx] = 1;
XX	else if (strcmp(line,"ADD") == NULL)
XX		code[indx] = 2;
XX	else if (strcmp(line,"SUB") == NULL)
XX		code[indx] = 3;
XX	else if (strcmp(line,"JMP") == NULL)
XX		code[indx] = 4;
XX	else if (strcmp(line,"JMZ") == NULL)
XX		code[indx] = 5;
XX	else if (strcmp(line,"JMG") == NULL)
XX		code[indx] = 6;
XX	else if (strcmp(line,"DJZ") == NULL)
XX		code[indx] = 7;
XX	else if (strcmp(line,"CMP") == NULL)
XX		code[indx] = 8;
XX	else if (strcmp(line,"DAT") == NULL)
XX		code[indx] = 0;
XX	else if (strcmp(line,"END") == NULL)
XX		return(NULL);
XX	else 
XX		return(ERROR);
XX	return(TRUE);
XX}
XX
XX/*
XX** get an argument value from line[]
XX*/
XXrdarg(md) char *md;
XX{
XX	char *pt; int i;
XX	pt = &line[0];
XX	if (*pt == '@') {
XX		*md = INDEXED;
XX		++pt;
XX	} else if (*pt == '#') {
XX		*md = IMMEDIATE;
XX		++pt;
XX	}
XX	i = stoi(pt);
XX	return(i);
XX}
XX
XX/*
XX** set the program counters to their initial locations
XX*/
XXgetpc(i) int i;
XX{
XX	fputs("\nStart execution at location: ",stderr);
XX	gets(line,12,stdin);
XX	pc[i] = stoi(line);
XX	pc[i] = reladr(pc[i],0);
XX}
XX
XX/*
XX** print programming header on screen
XX*/
XXheader(rw) int rw;
XX{
XX	cursor(rw,1);
XX	fputs("Addr",stderr);
XX	cursor(rw,10);
XX	fputs("Instr",stderr);
XX	cursor(rw,20);
XX	fputc('A',stderr);
XX	cursor(rw,30);
XX	fputc('B',stderr);
XX	cursor(rw,55);
XX	fputs("Modes:",stderr);
XX}
XX
XX/*
XX** Get the next word from a TEXTfile, making sure to capitalize
XX*/
XXnextword(fil) int fil;
XX{
XX	char *pt, c;
XX	pt = &line[0];
XX	c = '\t';
XX	while ((c == '\t') || (c == BLANK) || (c == CR) || (c == LF)) {
XX		if ((c = toupper(fgetc(fil))) == EOF)
XX			return (FALSE);
XX	}
XX	while ((c != '\t') && (c != BLANK) && (c != CR) && (c != LF)) {
XX		*pt++ = c;
XX		if ((c = toupper(fgetc(fil))) == EOF)
XX			return (FALSE);
XX	}
XX	*pt++ = '\0';
XX	return(TRUE);
XX}
XX
XX
XX
XX/*
XX** Show memory
XX*/
XXshowmem(start,finish) int start, finish;
XX{
XX	int ct;
XX	printf("Addresses %4d through %4d.\n",start,(finish-1));
XX	show = TRUE;
XX	putchar('\n');
XX	for (ct = start; ct < finish; ++ct) {
XX		readloc(ct);
XX		putchar('\n');
XX	}
XX}
XX	
XX/*
XX****************************
XX** MASTER BATTLE ROUTINES **
XX****************************
XX*/
XX
XX/*
XX** Fight it out
XX*/
XXfight()
XX{
XX	int ct, i;
XX	show = FALSE;
XX	fputs(CLRSCR,stderr);
XX	fputs("\tPRESS ANY KEY TO BEGIN ",stderr);
XX	while (bdos(06,0xff) == NULL);
XX	fputs("\n\nBeginning Battle...\n\n",stderr);
XX	fputs("\t> ^E to Abort <\n\n",stderr);
XX	printf("\t\t%8s\t\t%8s\n\n",proga,progb);
XX	for (ct = 0; ct < CUTOFF; ++ct) {
XX		if ((ct % 5) == 0)
XX			fputc('\n',stderr);
XX		stout(ct);
XX		now = 0;
XX		if (readloc(pc[0]) == NULL)
XX			break;
XX		putchar('\t');
XX		now = 1;
XX		if (readloc(pc[1]) == NULL)
XX			break;
XX		putchar('\n');
XX		if ((bdos(6,0xff)&0x7f) == ENQ)
XX			break;
XX		for (i = 0; i <2; ++i)
XX			pc[i] = reladr(pc[i],0);
XX	}
XX	fputc(BELL,stderr);
XX	printf("\nBattle Completed after %d instruction cycles!\n",ct);
XX	if (ct == CUTOFF)
XX		fputs("\>Draw<\n",stderr);
XX}	
XX
XX/*
XX** read a location, print the mnemonic, and perform it
XX*/
XXreadloc(loc) int loc;
XX{
XX	char ma, mb; int res;
XX	instr = modea = modeb = code[loc];
XX	instr &= 15;		/* or 0x0F */
XX	modea = (modea / 64) & 3;
XX	modeb = (modeb / 16) & 3;
XX	res = -1;
XX	if (instr == 1)			/* can't use switch with char arg */
XX		mov();
XX	else if (instr == 2)
XX		add();
XX	else if (instr == 3)
XX		sub();
XX	else if (instr == 4)
XX		jmp();
XX	else if (instr == 5)
XX		jmz();
XX	else if (instr == 6)
XX		jmg();
XX	else if (instr == 7)
XX		djz();
XX	else if (instr == 8)
XX		cmp();
XX	else {
XX		puts("DAT");
XX		res = NULL;
XX	}
XX	printf("\t%c%3d\t%c%3d [%3d]",mnem(modea),arga[loc],mnem(modeb),argb[loc],loc);
XX	return(res);
XX}
XX
XX/*
XX*********************************************
XX** functions to perform Redcode operations **
XX*********************************************
XX*/
XX
XX/*
XX** Redcode MOV instruction
XX*/
XXmov()
XX{
XX	int a,b;
XX	puts("MOV");
XX	if (show)
XX		return(NULL);
XX	b = findadr(pc[now], &argb[0], modeb);
XX	if (modea == IMMEDIATE) {
XX		code[b] = 0;			/* make it a DAT */
XX		argb[b] = arga[pc[now]];
XX#ifdef FULLIST
XX		printf("|#%6d>%3d|",arga[pc[now]],b);
XX#endif
XX	} else {
XX		a = findadr(pc[now], &arga[0], modea);
XX#ifdef FULLIST
XX		printf("|%3d>%3d|",a,b);
XX#endif
XX		code[b] = code[a];
XX		arga[b] = arga[a];
XX		argb[b] = argb[a];
XX	}
XX	++pc[now];
XX}
XX
XX/*
XX** Redcode ADD instruction
XX*/
XXadd()
XX{
XX	int a,b;
XX	puts("ADD");
XX	if (show)
XX		return(NULL);
XX	b = findadr(pc[now], &argb[0], modeb);
XX	if (modea == IMMEDIATE) {
XX		argb[b] += arga[pc[now]];
XX#ifdef FULLIST
XX		printf("|#%6d+%3d|",arga[pc[now]],b);
XX#endif
XX	} else {
XX		a = findadr(pc[now], &arga[0], modea);
XX#ifdef FULLIST
XX		printf("|%3d+%3d|",b,a);
XX#endif
XX		argb[b] += arga[a];
XX	}
XX	++pc[now];
XX}
XX
XX/*
XX** Redcode SUB instruction
XX*/
XXsub()
XX{
XX	int a,b;
XX	puts("SUB");
XX	if (show)
XX		return(NULL);
XX	b = findadr(pc[now], &argb[0], modeb);
XX	if (modea == IMMEDIATE) {
XX		argb[b] -= arga[pc[now]];
XX#ifdef FULLIST
XX		printf("|%3d-#%6d|",b,arga[pc[now]]);
XX#endif
XX	} else {
XX		a = findadr(pc[now], &arga[0],modea);
XX#ifdef FULLIST
XX		printf("|%3d-%3d|",b,a);
XX#endif
XX		argb[b] -= arga[a];
XX	}
XX	++pc[now];
XX}
XX
XX/*
XX** Redcode JMP Instruction
XX*/
XXjmp()
XX{
XX	int a;
XX	puts("JMP");
XX	if (show)
XX		return(NULL);
XX	pc[now] = findadr(pc[now], &arga[0], modea);
XX}
XX
XX/*
XX** Redcode JMZ instruction
XX*/
XXjmz()
XX{
XX	int b;
XX	puts("JMZ");
XX	if (show)
XX		return(NULL);
XX	b = findadr(pc[now], &argb[0], modeb);
XX#ifdef FULLIST
XX	printf("|%3d|",b);
XX#endif
XX	if (argb[b] == 0)
XX		pc[now] = findadr(pc[now], &arga[0], modea);
XX	else
XX		++pc[now];
XX}
XX
XX
XX/*
XX** Redcode JMG Instruction
XX*/
XXjmg()
XX{
XX	int b;
XX	puts("JMG");
XX	if (show)
XX		return(NULL);
XX	b = findadr(pc[now], &argb[0], modeb);
XX#ifdef FULLIST
XX	printf("|%3d|",b);
XX#endif
XX	if (argb[b] != 0)
XX		pc[now] = findadr(pc[now], &arga[0], modea);
XX	else
XX		++pc[now];
XX}
XX	
XX/*
XX** Redcode DJZ Instruction
XX*/
XXdjz()
XX{
XX	int b;
XX	puts("DJZ");
XX	if (show)
XX		return(NULL);
XX	b = findadr(pc[now], &argb[0], modeb);
XX#ifdef FULLIST
XX	printf("|%3d|",b);
XX#endif
XX	if ((--argb[b]) == NULL)
XX		pc[now] = findadr(pc[now], &arga[0], modea);
XX	else
XX		++pc[now];
XX}
XX
XX/*
XX** Redcode CMP Instruction
XX*/
XXcmp()
XX{
XX	int a,b;
XX	puts("CMP");
XX	if (show)
XX		return(NULL);
XX	if (modea != IMMEDIATE) {
XX		a = findadr(pc[now], &arga[0], modea);
XX		a = argb[a];
XX	} else
XX		a = arga[pc[now]];
XX	if (modeb != IMMEDIATE) {
XX		b = findadr(pc[now], &argb[0], modeb);
XX		b = argb[b];
XX	} else
XX		b = argb[pc[now]];
XX	++pc[now];
XX	if (a != b)
XX		++pc[now];
XX}
XX
XX/*
XX*************************
XX** Addressing Routines **
XX*************************
XX*/
XX
XX/*
XX** find an address via direct or indirect
XX*/
XXfindadr(orig,pab,mod) int orig, *pab; char mod;
XX{
XX	int p;
XX	if (mod == IMMEDIATE)
XX		return(orig);
XX	p = reladr(orig,pab[orig]);
XX	if (mod == INDEXED)
XX		p = reladr(p,argb[p]);
XX	return(p);
XX}
XX
XX
XX/*
XX** return an absolute address in the circular arena from a relative one
XX*/
XXreladr(abs,rel) int abs,rel;
XX{
XX	int j;
XX	if ((j = abs + rel) >= MAXSIZE)
XX		j = reladr((j - MAXSIZE),0);
XX	else if (j < 0)
XX		j = reladr((j + MAXSIZE),0);
XX	return(j);
XX}
XX
XX/*
XX****************************
XX** Miscellaneous routines **
XX****************************
XX*/
XX
XX/*
XX** Start with a "clean slate" in the battle-code arena
XX*/
XXclean()
XX{
XX	int i;
XX	for (i = 0; i < MAXSIZE; ++i) {
XX		code[i] = '\0';
XX		arga[i] = NULL;
XX		argb[i] = NULL;
XX	}
XX}
XX
XX/*
XX** return appropriate character for addressing modes
XX*/
XXmnem(c) char c;
XX{
XX	c &= 255;
XX	if (c == IMMEDIATE)
XX		return('#');
XX	else if (c == INDEXED)
XX		return('@');
XX	else
XX		return('.');
XX}
XX
XX/*
XX** return an integer from a string
XX*/
XXstoi(str) char *str;
XX{
XX	int i,s;
XX	if (*str == '-') {
XX		s = -1;
XX		++str;
XX	} else
XX		s = 1;
XX	i = 0;
XX	while ((*str >= '0') && (*str <= '9'))
XX		i = (10 * i) + (*str++ - '0');
XX	i *= s;
XX	return (i);
XX}
XX
XX/*
XX** print a string to stderr from an integer <= 9999
XX*/
XXstout(i) int i;
XX{
XX	if (i < 0)
XX		fputc('-',stderr);
XX	fputc((i / 1000 + '0'),stderr);
XX	i %= 1000;
XX	fputc((i / 100 + '0'),stderr);
XX	i %= 100;
XX	fputc((i / 10 + '0'),stderr);
XX	i %= 10;
XX	fputc((i + '0'),stderr);
XX	fputs(":\t",stderr);
XX}
XX
XX/*
XX** Address the cursor (Currently set for Heath/Telcon)
XX*/
XXcursor(row,col) int row,col;
XX{
XX	fputs(ADRCUR,stderr);
XX	fputc((row+BIAS),stderr);
XX	fputc((col+BIAS),stderr);
XX}
XX
XX/*
XX** raw console io
XX*/
XXkeypr()
XX{
XX	char c;
XX        while (!((c=bdos(6, 0xff)&0x7f)))
XX            ;
XX	return(c);
XX}
XX
XX/* end of CORE WARS 2 */
SHAR_EOF
if test 14508 -ne "`wc -c CoreOLD.c`"
then
echo shar: error transmitting CoreOLD.c '(should have been 14508 characters)'
fi
echo shar: extracting makefile
sed 's/^XX//' << \SHAR_EOF > makefile
XXOPT = 
XX
XXcorewar			: corewar.o
XX	ln corewar.o -lc
XXcorewar.o		: corewar.c corewar.h
XX	cc $(OPT) corewar.c
SHAR_EOF
if test 102 -ne "`wc -c makefile`"
then
echo shar: error transmitting makefile '(should have been 102 characters)'
fi
#	End of shell archive
exit 0