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