home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / pascal / corwar.zip / CORWAR.C next >
Text File  |  1992-03-15  |  15KB  |  783 lines

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