home *** CD-ROM | disk | FTP | other *** search
/ Hall of Fame / HallofFameCDROM.cdr / proglc / corewars.lzh / COREWARS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1986-04-18  |  15.0 KB  |  780 lines

  1.  
  2. /*    COREWARS 2.C    The game of Core Wars, as described by
  3. **            A.K. Dewdney in the May 1984 issue of
  4. **            Scientific American. 
  5. **
  6. **            Note: Output redirection will effect detailed
  7. **                  listings ONLY! (And it'll probably be a
  8. **                  BIG file.)
  9. **
  10. **    Date: 28 May 1984
  11. **    Author: Kevin A. Bjorke
  12. **
  13. **    Copyright (C) 1984 Kevin A. Bjorke
  14. **    Released to the Public Domain for Non-Commercial Use Only
  15. **
  16. **      7-June-1984 Bob Green
  17. **          Converted to MS-DOS 2.xx   -  Computer Innovations  C86
  18. **          and A TeleVideo 950 terminal from CP/M and Small-C 2.03  
  19. **
  20. */
  21.  
  22. #include "local.h"
  23.  
  24. #define MAXSIZE 1000        /* Dewdney has 8000 - change to your taste */
  25. #define VERSION "1.01"
  26. #define CLRSCR "\033*"        /* For Telcon, Heath, Etc. */
  27. #define ADRCUR "\033="        /* Likewise */
  28. #define BIAS 31            /* Ditto */
  29. #define INDEXED 2        /* Modes (Indexed = Indirect) */
  30. #define DIRECT 1
  31. #define IMMEDIATE 0
  32. #define CUTOFF 2000        /* Max. number of instructions executed */
  33. #define BLANK ' '
  34. #define CR 0x0d
  35. #define LF 0x0a
  36. #define ENQ 0x05
  37. #define FULLIST         /* List what's going where on MOV, ADD, etc */
  38. /*
  39. **********************
  40. ** Global Variables **
  41.  
  42. **********************
  43. */
  44.  
  45. char proga[80];            /* names of the battle programs */
  46. char progb[80];
  47.  
  48. int pc[2];            /* Redcode program counters */
  49. char instr;            /* Current instruction */
  50. int modea, modeb;        /* Current addressing modes -- see below */
  51. int now;            /* programs 0 and 1 (pc index) */
  52. char line[12];            /* large enough to accept anything required */
  53. char show;            /* used to differentiate between showing and */
  54.                 /* executing code */
  55.  
  56. char code[MAXSIZE];        /* Redcode Instructions */
  57. int  arga[MAXSIZE];        /* Battle Prog Arguments */
  58. int  argb[MAXSIZE];        /* Total: 5 bytes per ""location" */
  59.  
  60. /*
  61. ** Since the Redcode Instruction set has only 9 instruction and 3 addressing
  62. ** modes, the code is split into three fields:
  63. **
  64. **    Bit:    7 6 5 4 3 2 1 0
  65. **        a a b b i i i i
  66. **
  67. ** where a = mode of argument a
  68. **       b = mode of argument b
  69. **       i = instruction (0-8 -- 9-15 treated as 0, or invalid)
  70. **
  71. ** modes: 0 - immediate
  72. **        1 - direct
  73. **        2 - indirect
  74. */
  75.  
  76. /*
  77. *************************
  78. ** Main Program Driver **
  79. *************************
  80. */
  81.  
  82. main()    
  83. {
  84.     while (TRUE) {
  85.         logo();
  86.         clean();
  87.         prepare();
  88.         fight();
  89.         fputs("\nList Memory? ",stderr);
  90.         if (toupper(flgetc()) == 'Y')
  91.             showmem(0,MAXSIZE);
  92.         fputs("\n\nPlay Again (Y/N) ? ",stderr);
  93.         if (toupper(flgetc()) != 'Y')
  94.             break;
  95.     }
  96.     fputs("\n\n\tThththththat\'s all, folks....\n",stderr);
  97. }
  98.  
  99. /*
  100. ** Advertise the program
  101. */
  102. logo()
  103. {
  104.     fputs(CLRSCR,stderr);
  105.     fputs("\n\n\t****************************************\n",stderr);
  106.     fputs("\t**                                    **\n",stderr);
  107.     fputs("\t**         C O R E    W A R S         **\n",stderr);
  108.     fputs("\t**                                    **\n",stderr);
  109.     fputs("\t****************************************\n\n\n",stderr);
  110.     fputs("\tMARS Version ",stderr);
  111.     fputs(VERSION,stderr);
  112.     fputs("   Kevin Bjorke 5/28/84\n\n",stderr);
  113. }
  114.  
  115. /*
  116. ********************
  117. ** Input Routines **
  118. ********************
  119. */
  120.  
  121. /*
  122. ** Read in both programs
  123. */
  124. prepare()
  125. {
  126.     int top,bot; char *p;
  127.     int fp;            /* possible file pointer */
  128.     fputs("\n\tEnter the name of Battle-Program A: ",stderr);
  129.     gets(proga,80,stdin);
  130.     fputs("\n\tEnter the name of Battle-Program B: ",stderr);
  131.     gets(progb,80,stdin);
  132.     for (p = &progb[0]; *p; ++p)
  133.         *p = toupper(*p);
  134.     for (p = &proga[0]; *p; ++p)
  135.         *p = toupper(*p);
  136.     bot = 0;
  137.     if ((fp = fopen(proga,"r")) == NULL) {
  138.         fputs(CLRSCR,stderr);
  139.         fputs("\n\nPlease enter code for ",stderr);
  140.         fputs(proga,stderr);
  141.         fputs(":\n\n",stderr);
  142.         top = getprog(proga,bot);
  143.     } else
  144.         top = fgetprog(fp,bot);
  145.     printf("\nNow listing Program %s:\n\n",proga);
  146.     showmem(bot,top);
  147.     pc[0] = bot;
  148.     getpc(0);
  149.     bot = MAXSIZE / 2;
  150.     if ((fp = fopen(progb,"r")) == NULL) {
  151.         fputs(CLRSCR,stderr);
  152.         fputs("\n\nNow, please enter code for ",stderr);
  153.         fputs(progb,stderr);
  154.         fputs(":\n\n",stderr);
  155.         top = getprog(progb,bot);
  156.     } else
  157.         top = fgetprog(fp,bot);
  158.     printf("\nNow listing Program %s:\n\n",progb);
  159.     showmem(bot,top);
  160.     pc[1] = bot;
  161.     getpc(1);
  162. }
  163.  
  164. /*
  165. ** get a program from the keyboard
  166. */
  167. getprog(prg,ct) char *prg; int ct;
  168. {
  169.     int i,row; 
  170.         char *pt;
  171.     row = 10;
  172.     fputs("Enter program one line at a time.\n",stderr);
  173.     fputs("Pressing RETURN between arguments.\n",stderr);
  174.     fputs("\tUse END to finish\n\n",stderr);
  175.     header(9);
  176.     while (TRUE) {
  177.         modea = modeb = DIRECT;
  178.         cursor(row,1);
  179.         stout(ct);
  180.         cursor(row,10);
  181.         gets(line,12,stdin);
  182.         for (i = 0; line[i]; ++i) {
  183.             if ((line[i] == '\t') || (line[i] == ' '))
  184.                 line[i] = '\0';
  185.             line[i] = toupper(line[i]);
  186.         }
  187.         if ((i = getinst(ct)) == NULL)
  188.             break;
  189.         if (i == ERROR) {
  190.             cursor(row,10);
  191.             fputs("\007???\n",stderr);
  192.             continue;
  193.         }
  194.         cursor(row,50);
  195.         fputs(line,stderr);
  196.         if (code[ct] != 0) {
  197.             cursor(row,20);
  198.             gets(line,12,stdin);
  199.             pt = &line[0];
  200.             cursor(row,60);
  201.             if (*pt == '@') {
  202.                 fputs("Indirect",stderr);
  203.                 modea = INDEXED;
  204.                 ++pt;
  205.             } else if (*pt == '#') {
  206.                 fputs("Immediate",stderr);
  207.                 modea = IMMEDIATE;
  208.                 ++pt;
  209.             }  else
  210.                 fputs("Direct",stderr);
  211.             i = stoi(pt);
  212.             arga[ct] = i;
  213.         }
  214.         if (code[ct] != 4) {
  215.             cursor(row,30);
  216.             gets(line,12,stdin);
  217.             pt = &line[0];
  218.             cursor(row,70);
  219.             if (*pt == '@') {
  220.                 fputs("Indirect",stderr);
  221.                 modeb = INDEXED;
  222.                 ++pt;
  223.             } else if (*pt == '#') {
  224.                 fputs("Immediate",stderr);
  225.                 modeb = IMMEDIATE;
  226.                 ++pt;
  227.             } else
  228.                 fputs("Direct",stderr);
  229.             i = stoi(pt);
  230.             argb[ct] = i;
  231.         }
  232.         modea *= 64;
  233.         modea &= 192;
  234.         modeb *= 16;
  235.         modeb &= 48;
  236.         code[ct] += (modea + modeb);
  237.         ++ct;
  238.         if ((++row) > 23) {
  239.             row = 2;
  240.             fputs(CLRSCR,stderr);
  241.             header(1);
  242.         }
  243.     }
  244.     fputs("\n\tCode for ",stderr);
  245.     fputs(prg,stderr);
  246.     fputs(" completed.\n",stderr);
  247.     return(ct);
  248. }
  249.  
  250. /*
  251. ** get a program from a file
  252. */
  253. fgetprog(prg,ct) int prg,ct;
  254. {
  255.     int i; char *pt;
  256.     fputs("\nNow reasding program file...\n\n",stderr);
  257.     while (TRUE) {
  258.         modea = modeb = DIRECT;
  259.         if (nextword(prg) == FALSE)
  260.             break;
  261.         if ((i = getinst(ct)) == NULL)
  262.             break;
  263.         if (i == ERROR) {
  264.             fputs("\007\nError - file fouled up!!!\n",stderr);
  265.             exit();
  266.         }
  267.         if (code[ct] != 0) {
  268.             nextword(prg);
  269.             arga[ct] = rdarg(&modea);
  270.         }
  271.         if (code[ct] != 4) {
  272.             nextword(prg);
  273.             argb[ct] = rdarg(&modeb);
  274.         }
  275.         modea *= 64;
  276.         modea &= 192;
  277.         modeb *= 16;
  278.         modeb &= 48;
  279.         code[ct] += (modea + modeb);
  280.         ++ct;
  281.     }
  282.     fclose(prg);
  283.     return(ct);
  284. }
  285.  
  286. /*
  287. ** select an instruction from the vaule in line[]
  288. */
  289. getinst(indx) int indx;
  290. {
  291.     if (strcmp(line,"MOV") == NULL)
  292.         code[indx] = 1;
  293.     else if (strcmp(line,"ADD") == NULL)
  294.         code[indx] = 2;
  295.     else if (strcmp(line,"SUB") == NULL)
  296.         code[indx] = 3;
  297.     else if (strcmp(line,"JMP") == NULL)
  298.         code[indx] = 4;
  299.     else if (strcmp(line,"JMZ") == NULL)
  300.         code[indx] = 5;
  301.     else if (strcmp(line,"JMG") == NULL)
  302.         code[indx] = 6;
  303.     else if (strcmp(line,"DJZ") == NULL)
  304.         code[indx] = 7;
  305.     else if (strcmp(line,"CMP") == NULL)
  306.         code[indx] = 8;
  307.     else if (strcmp(line,"DAT") == NULL)
  308.         code[indx] = 0;
  309.     else if (strcmp(line,"END") == NULL)
  310.         return(NULL);
  311.     else 
  312.         return(ERROR);
  313.     return(TRUE);
  314. }
  315.  
  316. /*
  317. ** get an argument value from line[]
  318. */
  319. rdarg(md) char *md;
  320. {
  321.     char *pt; int i;
  322.     pt = &line[0];
  323.     if (*pt == '@') {
  324.         *md = INDEXED;
  325.         ++pt;
  326.     } else if (*pt == '#') {
  327.         *md = IMMEDIATE;
  328.         ++pt;
  329.     }
  330.     i = stoi(pt);
  331.     return(i);
  332. }
  333.  
  334. /*
  335. ** set the program counters to their initial locations
  336. */
  337. getpc(i) int i;
  338. {
  339.     fputs("\nStart execution at location: ",stderr);
  340.     gets(line,12,stdin);
  341.     pc[i] = stoi(line);
  342.     pc[i] = reladr(pc[i],0);
  343. }
  344.  
  345. /*
  346. ** print programming header on screen
  347. */
  348. header(rw) int rw;
  349. {
  350.     cursor(rw,1);
  351.     fputs("Addr",stderr);
  352.     cursor(rw,10);
  353.     fputs("Instr",stderr);
  354.     cursor(rw,20);
  355.     fputc('A',stderr);
  356.     cursor(rw,30);
  357.     fputc('B',stderr);
  358.     cursor(rw,55);
  359.     fputs("Modes:",stderr);
  360. }
  361.  
  362. /*
  363. ** Get the next word from a TEXTfile, making sure to capitalize
  364. */
  365. nextword(fil) int fil;
  366. {
  367.     char *pt, c;
  368.     pt = &line[0];
  369.     c = '\t';
  370.     while ((c == '\t') || (c == BLANK) || (c == CR) || (c == LF)) {
  371.         if ((c = toupper(fgetc(fil))) == EOF)
  372.             return (FALSE);
  373.     }
  374.     while ((c != '\t') && (c != BLANK) && (c != CR) && (c != LF)) {
  375.         *pt++ = c;
  376.         if ((c = toupper(fgetc(fil))) == EOF)
  377.             return (FALSE);
  378.     }
  379.     *pt++ = '\0';
  380.     return(TRUE);
  381. }
  382.  
  383.  
  384.  
  385. /*
  386. ** Show memory
  387. */
  388. showmem(start,finish) int start, finish;
  389. {
  390.     int ct;
  391.     printf("Addresses %4d through %4d.\n",start,(finish-1));
  392.     show = TRUE;
  393.     putchar('\n');
  394.     for (ct = start; ct < finish; ++ct) {
  395.         readloc(ct);
  396.         putchar('\n');
  397.     }
  398. }
  399.     
  400. /*
  401. ****************************
  402. ** MASTER BATTLE ROUTINES **
  403. ****************************
  404. */
  405.  
  406. /*
  407. ** Fight it out
  408. */
  409. fight()
  410. {
  411.     int ct, i;
  412.     show = FALSE;
  413.     fputs(CLRSCR,stderr);
  414.     fputs("\tPRESS ANY KEY TO BEGIN ",stderr);
  415.     while (bdos(06,0xff) == NULL);
  416.     fputs("\n\nBeginning Battle...\n\n",stderr);
  417.     fputs("\t> ^E to Abort <\n\n",stderr);
  418.     printf("\t\t%8s\t\t%8s\n\n",proga,progb);
  419.     for (ct = 0; ct < CUTOFF; ++ct) {
  420.         if ((ct % 5) == 0)
  421.             fputc('\n',stderr);
  422.         stout(ct);
  423.         now = 0;
  424.         if (readloc(pc[0]) == NULL)
  425.             break;
  426.         putchar('\t');
  427.         now = 1;
  428.         if (readloc(pc[1]) == NULL)
  429.             break;
  430.         putchar('\n');
  431.         if ((bdos(6,0xff)&0x7f) == ENQ)
  432.             break;
  433.         for (i = 0; i <2; ++i)
  434.             pc[i] = reladr(pc[i],0);
  435.     }
  436.     fputc(BELL,stderr);
  437.     printf("\nBattle Completed after %d instruction cycles!\n",ct);
  438.     if (ct == CUTOFF)
  439.         fputs("\>Draw<\n",stderr);
  440. }    
  441.  
  442. /*
  443. ** read a location, print the mnemonic, and perform it
  444. */
  445. readloc(loc) int loc;
  446. {
  447.     char ma, mb; int res;
  448.     instr = modea = modeb = code[loc];
  449.     instr &= 15;        /* or 0x0F */
  450.     modea = (modea / 64) & 3;
  451.     modeb = (modeb / 16) & 3;
  452.     res = -1;
  453.     if (instr == 1)            /* can't use switch with char arg */
  454.         mov();
  455.     else if (instr == 2)
  456.         add();
  457.     else if (instr == 3)
  458.         sub();
  459.     else if (instr == 4)
  460.         jmp();
  461.     else if (instr == 5)
  462.         jmz();
  463.     else if (instr == 6)
  464.         jmg();
  465.     else if (instr == 7)
  466.         djz();
  467.     else if (instr == 8)
  468.         cmp();
  469.     else {
  470.         puts("DAT");
  471.         res = NULL;
  472.     }
  473.     printf("\t%c%3d\t%c%3d [%3d]",mnem(modea),arga[loc],mnem(modeb),argb[loc],loc);
  474.     return(res);
  475. }
  476.  
  477. /*
  478. *********************************************
  479. ** functions to perform Redcode operations **
  480. *********************************************
  481. */
  482.  
  483. /*
  484. ** Redcode MOV instruction
  485. */
  486. mov()
  487. {
  488.     int a,b;
  489.     puts("MOV");
  490.     if (show)
  491.         return(NULL);
  492.     b = findadr(pc[now], &argb[0], modeb);
  493.     if (modea == IMMEDIATE) {
  494.         code[b] = 0;            /* make it a DAT */
  495.         argb[b] = arga[pc[now]];
  496. #ifdef FULLIST
  497.         printf("|#%6d>%3d|",arga[pc[now]],b);
  498. #endif
  499.     } else {
  500.         a = findadr(pc[now], &arga[0], modea);
  501. #ifdef FULLIST
  502.         printf("|%3d>%3d|",a,b);
  503. #endif
  504.         code[b] = code[a];
  505.         arga[b] = arga[a];
  506.         argb[b] = argb[a];
  507.     }
  508.     ++pc[now];
  509. }
  510.  
  511. /*
  512. ** Redcode ADD instruction
  513. */
  514. add()
  515. {
  516.     int a,b;
  517.     puts("ADD");
  518.     if (show)
  519.         return(NULL);
  520.     b = findadr(pc[now], &argb[0], modeb);
  521.     if (modea == IMMEDIATE) {
  522.         argb[b] += arga[pc[now]];
  523. #ifdef FULLIST
  524.         printf("|#%6d+%3d|",arga[pc[now]],b);
  525. #endif
  526.     } else {
  527.         a = findadr(pc[now], &arga[0], modea);
  528. #ifdef FULLIST
  529.         printf("|%3d+%3d|",b,a);
  530. #endif
  531.         argb[b] += arga[a];
  532.     }
  533.     ++pc[now];
  534. }
  535.  
  536. /*
  537. ** Redcode SUB instruction
  538. */
  539. sub()
  540. {
  541.     int a,b;
  542.     puts("SUB");
  543.     if (show)
  544.         return(NULL);
  545.     b = findadr(pc[now], &argb[0], modeb);
  546.     if (modea == IMMEDIATE) {
  547.         argb[b] -= arga[pc[now]];
  548. #ifdef FULLIST
  549.         printf("|%3d-#%6d|",b,arga[pc[now]]);
  550. #endif
  551.     } else {
  552.         a = findadr(pc[now], &arga[0],modea);
  553. #ifdef FULLIST
  554.         printf("|%3d-%3d|",b,a);
  555. #endif
  556.         argb[b] -= arga[a];
  557.     }
  558.     ++pc[now];
  559. }
  560.  
  561. /*
  562. ** Redcode JMP Instruction
  563. */
  564. jmp()
  565. {
  566.     int a;
  567.     puts("JMP");
  568.     if (show)
  569.         return(NULL);
  570.     pc[now] = findadr(pc[now], &arga[0], modea);
  571. }
  572.  
  573. /*
  574. ** Redcode JMZ instruction
  575. */
  576. jmz()
  577. {
  578.     int b;
  579.     puts("JMZ");
  580.     if (show)
  581.         return(NULL);
  582.     b = findadr(pc[now], &argb[0], modeb);
  583. #ifdef FULLIST
  584.     printf("|%3d|",b);
  585. #endif
  586.     if (argb[b] == 0)
  587.         pc[now] = findadr(pc[now], &arga[0], modea);
  588.     else
  589.         ++pc[now];
  590. }
  591.  
  592.  
  593. /*
  594. ** Redcode JMG Instruction
  595. */
  596. jmg()
  597. {
  598.     int b;
  599.     puts("JMG");
  600.     if (show)
  601.         return(NULL);
  602.     b = findadr(pc[now], &argb[0], modeb);
  603. #ifdef FULLIST
  604.     printf("|%3d|",b);
  605. #endif
  606.     if (argb[b] != 0)
  607.         pc[now] = findadr(pc[now], &arga[0], modea);
  608.     else
  609.         ++pc[now];
  610. }
  611.     
  612. /*
  613. ** Redcode DJZ Instruction
  614. */
  615. djz()
  616. {
  617.     int b;
  618.     puts("DJZ");
  619.     if (show)
  620.         return(NULL);
  621.     b = findadr(pc[now], &argb[0], modeb);
  622. #ifdef FULLIST
  623.     printf("|%3d|",b);
  624. #endif
  625.     if ((--argb[b]) == NULL)
  626.         pc[now] = findadr(pc[now], &arga[0], modea);
  627.     else
  628.         ++pc[now];
  629. }
  630.  
  631. /*
  632. ** Redcode CMP Instruction
  633. */
  634. cmp()
  635. {
  636.     int a,b;
  637.     puts("CMP");
  638.     if (show)
  639.         return(NULL);
  640.     if (modea != IMMEDIATE) {
  641.         a = findadr(pc[now], &arga[0], modea);
  642.         a = argb[a];
  643.     } else
  644.         a = arga[pc[now]];
  645.     if (modeb != IMMEDIATE) {
  646.         b = findadr(pc[now], &argb[0], modeb);
  647.         b = argb[b];
  648.     } else
  649.         b = argb[pc[now]];
  650.     ++pc[now];
  651.     if (a != b)
  652.         ++pc[now];
  653. }
  654.  
  655. /*
  656. *************************
  657. ** Addressing Routines **
  658. *************************
  659. */
  660.  
  661. /*
  662. ** find an address via direct or indirect
  663. */
  664. findadr(orig,pab,mod) int orig, *pab; char mod;
  665. {
  666.     int p;
  667.     if (mod == IMMEDIATE)
  668.         return(orig);
  669.     p = reladr(orig,pab[orig]);
  670.     if (mod == INDEXED)
  671.         p = reladr(p,argb[p]);
  672.     return(p);
  673. }
  674.  
  675.  
  676. /*
  677. ** return an absolute address in the circular arena from a relative one
  678. */
  679. reladr(abs,rel) int abs,rel;
  680. {
  681.     int j;
  682.     if ((j = abs + rel) >= MAXSIZE)
  683.         j = reladr((j - MAXSIZE),0);
  684.     else if (j < 0)
  685.         j = reladr((j + MAXSIZE),0);
  686.     return(j);
  687. }
  688.  
  689. /*
  690. ****************************
  691. ** Miscellaneous routines **
  692. ****************************
  693. */
  694.  
  695. /*
  696. ** Start with a "clean slate" in the battle-code arena
  697. */
  698. clean()
  699. {
  700.     int i;
  701.     for (i = 0; i < MAXSIZE; ++i) {
  702.         code[i] = '\0';
  703.         arga[i] = NULL;
  704.         argb[i] = NULL;
  705.     }
  706. }
  707.  
  708. /*
  709. ** return appropriate character for addressing modes
  710. */
  711. mnem(c) char c;
  712. {
  713.     c &= 255;
  714.     if (c == IMMEDIATE)
  715.         return('#');
  716.     else if (c == INDEXED)
  717.         return('@');
  718.     else
  719.         return('.');
  720. }
  721.  
  722. /*
  723. ** return an integer from a string
  724. */
  725. stoi(str) char *str;
  726. {
  727.     int i,s;
  728.     if (*str == '-') {
  729.         s = -1;
  730.         ++str;
  731.     } else
  732.         s = 1;
  733.     i = 0;
  734.     while ((*str >= '0') && (*str <= '9'))
  735.         i = (10 * i) + (*str++ - '0');
  736.     i *= s;
  737.     return (i);
  738. }
  739.  
  740. /*
  741. ** print a string to stderr from an integer <= 9999
  742. */
  743. stout(i) int i;
  744. {
  745.     if (i < 0)
  746.         fputc('-',stderr);
  747.     fputc((i / 1000 + '0'),stderr);
  748.     i %= 1000;
  749.     fputc((i / 100 + '0'),stderr);
  750.     i %= 100;
  751.     fputc((i / 10 + '0'),stderr);
  752.     i %= 10;
  753.     fputc((i + '0'),stderr);
  754.     fputs(":\t",stderr);
  755. }
  756.  
  757. /*
  758. ** Address the cursor (Currently set for Heath/Telcon)
  759. */
  760. cursor(row,col) int row,col;
  761. {
  762.     fputs(ADRCUR,stderr);
  763.     fputc((row+BIAS),stderr);
  764.     fputc((col+BIAS),stderr);
  765. }
  766.  
  767. /*
  768. ** raw console io
  769. */
  770. keypr()
  771. {
  772.     char c;
  773.         while (!((c=bdos(6, 0xff)&0x7f)))
  774.             ;
  775.     return(c);
  776. }
  777.  
  778. /* end of CORE WARS 2 */
  779.  
  780.