diff --git a/README.md b/README.md index 67d022c..0cb7bb2 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ See this repository: https://git.imzadi.de/acn/backgammon-vt100 * [Sokoban](Sokoban/) * [Battleships](Battleships/) * [Blocks](Blocks/) +* [Robots](Robots/) ## More Games on the Interwebs diff --git a/Robots/README.md b/Robots/README.md new file mode 100644 index 0000000..dc6d6a3 --- /dev/null +++ b/Robots/README.md @@ -0,0 +1,48 @@ +# Robots + +Robots is a turn-based game for CP/M. + +It's based on ROBOTS, a BSD game (but no source code was taken from it). + +The objetive of the robots is only one: to kill you. + +The only thing you can do, is to try to escape from them. But use the teletransportation with care: you have only a few teletransport tickets! + +The robots will die if they collide between them or crash against something. + +That's your only opportunity to win the robots. + +Good luck! + +Copyright (c) 2015 Miguel García / FloppySoftware + +A 'clear screen' function (VT100) has been added by me (Anna Christina Naß . + +Original Repository: https://github.com/MiguelVis/RetroProjects +Website: http://www.floppysoftware.es/robots.html?path=cpm_projects|robots + +The file ``ROBOTS.COM`` is the compiled game file. + +## Commands + +Move the player ``.P.`` using the numpad numbers as shown on the screen. +Press T for teletransportation and Q for quit. + +## Compile: + +To compile, use MESCC, "Mike's Enhanced Small C Compiler". +See: http://www.floppysoftware.es/mescc.html?path=cpm_projects|mescc + +In the directory ``mescc``, I provide the files neccessary to compile Robots, using: + + CC ROBOTS + CCOPT ROBOTS + ZSM ROBOTS + HEXTOCOM ROBOTS + +Note that only the really neccessary files are provided - see the link above for the full MESCC compiler and source code! + +## License: + +GPL Version 2, see copying.txt - valid for MESCC and Robots. + diff --git a/Robots/ROBOTS.COM b/Robots/ROBOTS.COM new file mode 100644 index 0000000..3e48ae7 Binary files /dev/null and b/Robots/ROBOTS.COM differ diff --git a/Robots/copying.txt b/Robots/copying.txt new file mode 100644 index 0000000..a43ea21 --- /dev/null +++ b/Robots/copying.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Robots/mescc/CC.COM b/Robots/mescc/CC.COM new file mode 100644 index 0000000..e9d6115 Binary files /dev/null and b/Robots/mescc/CC.COM differ diff --git a/Robots/mescc/CCOPT.COM b/Robots/mescc/CCOPT.COM new file mode 100644 index 0000000..1566fe5 Binary files /dev/null and b/Robots/mescc/CCOPT.COM differ diff --git a/Robots/mescc/HEXTOCOM.COM b/Robots/mescc/HEXTOCOM.COM new file mode 100644 index 0000000..202be89 Binary files /dev/null and b/Robots/mescc/HEXTOCOM.COM differ diff --git a/Robots/mescc/ZSM.COM b/Robots/mescc/ZSM.COM new file mode 100644 index 0000000..5ce1976 Binary files /dev/null and b/Robots/mescc/ZSM.COM differ diff --git a/Robots/mescc/conio.h b/Robots/mescc/conio.h new file mode 100644 index 0000000..895a683 --- /dev/null +++ b/Robots/mescc/conio.h @@ -0,0 +1,252 @@ +/** + * @file conio.h + * @brief Console I/O. + * @author Miguel I. Garcia Lopez / FloppySoftware + * + * Console I/O functions, for MESCC (Mike's Enhanced + * Small C Compiler for Z80 & CP/M). + * + * Supports following #defines: + * - CC_STDIO Support for stdin, stdout & stderr. + * - CC_CONIO_BIOS Support for direct console I/O. + * + * Revisions: + * - 22 Jan 2001 : Last revision. + * - 16 Apr 2007 : GPL'd. + * - 21 Apr 2007 : Changed puts for ANSI compatibility. + * - 15 May 2007 : Bug solved - added LF output to puts. + * - 13 Jul 2014 : Added kbhit(). + * - 08 Dec 2014 : Added support for stdin, stdout & stderr. + * - 31 Dec 2014 : Solved bug in putstr when characters are > 0x7F. + * - 20 Dec 2015 : Added macro CC_CONIO_BIOS to support direct console I/O using BIOS, instead of BDOS. + * - 08 Jan 2015 : Modified getch() when access BDOS (fn. 6 instead of 1). + * - 10 Dec 2016 : Documented. GPL v3. + * + * Copyright (c) 1999-2016 Miguel I. Garcia Lopez / FloppySoftware. + * + * Licensed under the GNU General Public License v3. + * + * http://www.floppysoftware.es + * floppysoftware@gmail.com + */ +#ifndef CONIO_H + +#define CONIO_H + +/** + * @fn int putch(int ch) + * @brief Send character to the console. + * @param ch - character + * @return ch + */ +#ifdef CC_CONIO_BIOS +#asm + +putch + PUSH HL + LD C,L + LD E,9 + CALL xbios + POP HL + RET + +xbios + LD HL,(1) + LD D,0 + ADD HL,DE + JP (HL) + +#endasm +#else +#asm + +putch + PUSH HL + LD C,2 + LD E,L + CALL 5 + POP HL + RET +#endasm +#endif + +/** + * @fn int getch(void) + * @brief Get character from the console without echo. + * + * Waits until a character is available. + * + * @return character + */ +#ifdef CC_CONIO_BIOS +#asm + +getch + LD E,6 + CALL xbios + LD H,0 + LD L,A + RET + +#endasm +#else +#asm + +getch + LD C,6 + LD E,255 + CALL 5 + OR A + JR Z,getch + LD H,0 + LD L,A + RET +#endasm +#endif + +/** + * @fn int kbhit(void) + * @brief Tests console input status. + * @return != 0 if a character is available, else 0. + */ +#ifdef CC_CONIO_BIOS +#asm + +kbhit + LD E, 3 + CALL xbios + LD H,A + LD L,A + RET + +#endasm +#else +#asm + +kbhit + LD C,11 + CALL 5 + LD H,A + LD L,A + RET +#endasm +#endif + +/** + * @fn int getchar(void) + * @brief Get character from the console or stdin. + * + * Waits until a character is available. + * + * #ifdef CC_STDIO: Returns a character from stdin, or EOF on end of file or error. + * #ifndef CC_STDIO: Returns a character from the console. Echoes the character. + * + * @return character on success, else EOF. + */ +getchar() +{ + +#ifdef CC_STDIO + + return fgetc(stdin); + +#else + + return putchar(getch()); + +#endif + +} + +/** + * @fn int putchar(int ch) + * @brief Send character to the console or stdout. + * + * #ifdef CC_STDIO: Returns ch, or EOF on error. + * #ifndef CC_STDIO: Returns ch. + * + * @param ch - character + * @return ch on success, else EOF. + */ +putchar(ch) +int ch; +{ + +#ifdef CC_STDIO + + return fputc(ch, stdout); + +#else + + if(ch == '\n') + putch('\r'); + + return putch(ch); + +#endif + +} + +/** + * @fn int putstr(char *s) + * @brief Send string to the console or stdout. + * + * #ifdef CC_STDIO: Returns the number of characters sent, or EOF on error. + * #ifndef CC_STDIO: Returns a non-negative value to indicate success. + * + * @param s - string + * @return number of characters sent on success, else EOF. + */ +putstr(s) +char *s; +{ + +#ifdef CC_STDIO + + /* FIXME : Better if call to fputs (if available) */ + + int i, c; + + i = 0; + + while(*s) + { + /* FIXME : -1 hardcoded -- < 0 causes strange + behaviour if ch > 0x7F */ + + if((c = putchar(*s++)) == -1) + return c; + ++i; + } + + return i; +#else + while(*s) + putchar(*s++); + + return 0; +#endif + +} + +/** + * @fn int puts(char *s) + * @brief Send string + '\n' to the console or stdout. + * + * #ifdef CC_STDIO: Returns the number of characters sent, or EOF on error. + * #ifndef CC_STDIO: Returns a non-negative value to indicate success. + * + * @param s - string + * @return number of characters sent on success, else EOF. + */ +puts(s) +char *s; +{ + putstr(s); + + return putchar('\n'); /* FIXME */ +} + +#endif + + \ No newline at end of file diff --git a/Robots/mescc/ctype.h b/Robots/mescc/ctype.h new file mode 100644 index 0000000..bad2be9 --- /dev/null +++ b/Robots/mescc/ctype.h @@ -0,0 +1,203 @@ +/** + * @file ctype.h + * @brief Character tests and conversion functions. + * @author Miguel I. Garcia Lopez / FloppySoftware + * + * Character tests and conversion functions, for MESCC (Mike's Enhanced + * Small C Compiler for Z80 & CP/M). + * + * Revisions: + * - 19 Dec 2000 : Last revision. + * - 16 Apr 2007 : GPL'd. + * - 15 Aug 2016 : Documented. GPL v3. + * + * Copyright (c) 1999-2016 Miguel I. Garcia Lopez / FloppySoftware. + * + * Licensed under the GNU General Public License v3. + * + * http://www.floppysoftware.es + * floppysoftware@gmail.com + */ +#ifndef CTYPE_H + +#define CTYPE_H + +/** + * @fn int isalpha(char ch) + * @brief Test if ch is a letter. + * @param ch - character to test + * @return true or false + */ +#asm + +isalpha + ld a,l + ld hl,0 + cp 'A' + ret c + cp 'Z'+1 + jr c,isalpha1 + cp 'a' + ret c + cp 'z'+1 + ret nc +isalpha1 + inc l + ret + +#endasm + +/** + * @fn int isdigit(char ch) + * @brief Test if ch is a decimal digit. + * @param ch - character to test + * @return true or false + */ +#asm + +isdigit + ld a,l + ld hl,0 + cp '0' + ret c + cp '9'+1 + ret nc + inc l + ret + +#endasm + +/** + * @fn int isxdigit(char ch) + * @brief Test if ch is an hexadecimal digit. + * @param ch - character to test + * @return true or false + */ +#asm + +isxdigit + LD C,L + CALL isdigit + RET C + LD HL,0 + LD A,C + CP 'A' + RET C + CP 'G' + JR C,isxdigit1 + CP 'a' + RET C + CP 'g' + RET NC +isxdigit1 + INC L + RET + +#endasm + +/** + * @fn int isalnum(char ch) + * @brief Test if ch is a letter or a decimal digit. + * @param ch - character to test + * @return true or false + */ +#asm + +isalnum + LD C,L + CALL isdigit + RET C + LD L,C + JP isalpha + +#endasm + +/** + * @fn int isupper(char ch) + * @brief Test if ch is a letter in uppercase. + * @param ch - character to test + * @return true or false + */ +#asm + +isupper + ld a,l + ld hl,0 + cp 'A' + ret c + cp 'Z'+1 + ret nc + inc l + ret + +#endasm + +/** + * @fn int islower(char ch) + * @brief Test if ch is a letter in lowercase. + * @param ch - character to test + * @return true or false + */ +#asm + +islower + ld a,l + ld hl,0 + cp 'a' + ret c + cp 'z'+1 + ret nc + inc l + ret + +#endasm + +/** + * @fn int toupper(char ch) + * @brief Convert letter to uppercase. + * + * If ch is not a letter in lowercase, returns ch unchanged. + * + * @param ch - character to convert + * @return ch in uppercase + */ +#asm + +toupper + ld a,l + cp 'a' + ret c + cp 'z'+1 + ret nc + sub 20h + ld l,a + ret + +#endasm + +/** + * @fn int tolower(char ch) + * @brief Convert letter to lowercase. + * + * If ch is not a letter in uppercase, returns ch unchanged. + * + * @param ch - character to convert + * @return ch in lowercase + */ +#asm + +tolower + ld a,l + cp 'A' + ret c + cp 'Z'+1 + ret nc + add 20h + ld l,a + ret + +#endasm + +#endif + + \ No newline at end of file diff --git a/Robots/mescc/mescc.h b/Robots/mescc/mescc.h new file mode 100644 index 0000000..d826374 --- /dev/null +++ b/Robots/mescc/mescc.h @@ -0,0 +1,945 @@ +/** + * @file mescc.h + * @brief Runtime library. + * @author Miguel I. Garcia Lopez / FloppySoftware + * + * Runtime library for MESCC (Mike's Enhanced + * Small C Compiler for Z80 & CP/M). + * + * This library file must be included first! + * + * Need following EQU's (generated by the compiler): + * - ccSTACKSIZE : Stack size in bytes. + * + * Supports following #defs: + * - #define CC_STDIO Support for stdin, stdout & stderr. + * - #define CC_REDIR Support for stdin & stdout redirection + * in command line (needs CC_STDIO). + * - #define CC_NO_MUL To exclude MULTIPLICATION code. + * - #define CC_NO_DIV To exclude DIVISION & MODULUS code. + * - #define CC_NO_SWITCH To exclude SWITCH code. + * - #define CC_NO_ARGS To exclude ARGC & ARGV code. + * - #define CC_NO_ORG To exclude ORG 0100H code. + * + * Sets the following #defines: + * + * - BYTE + * - WORD + * - BOOL + * - NULL + * - TRUE + * - FALSE + * - SIZEOF_CHAR + * - SIZEOF_INT + * - SIZEOF_PTR + * + * Revisions: + * - 16 Jan 2001 : Last revision. + * - 23 Mar 2007 : Expand ccladr1 and ccladr2 for more speed. + * - 16 Apr 2007 : GPL'd. + * - 26 Aug 2012 : Added standard defs. + * - 08 Dec 2014 : Minor changes. + * - 09 Dec 2014 : Added support for stdin, stdout & stderr with CC_STDIO. + * - 12 Dec 2014 : Added support for stdin & stdout redirection in command line with CC_REDIR. + * - 16 Jan 2015 : Added SIZEOF_??? definitions. + * - 16 Feb 2015 : Modified / added code in cctmpw, ccxpb2, ccxpb, ccxpb3, ccxpw2 + * ccxpw, ccxpw3, ccladr2sv, ccladr2, ccladr1sv, ccladr1, + * to avoid use of IX register. + * - 20 Mar 2015 : Added support for CC_NO_MUL, CC_NO_DIV, CC_NO_SWITCH, CC_NO_ARGS. + * - 12 Apr 2015 : Removed ccDEFARGS code. + * - 14 Jul 2015 : Modified code for << and >>, because a shift of 0 positions, + * resulted in a wrong value (they assumed a shift > 0) - ie: 128 >> 0 resulted in 0. + * - 19 Oct 2015 : Improved multiplication algorithm (ccmul & ccumul). + * - 05 Nov 2015 : Modified ccsxt. + * - 30 Nov 2015 : Added support for atexit(). + * - 24 Jan 2016 : Added support for CC_NO_ORG. + * - 10 Dec 2016 : Documented. GPL v3. + * + * Copyright (c) 1999-2016 Miguel I. Garcia Lopez / FloppySoftware. + * + * Licensed under the GNU General Public License v3. + * + * http://www.floppysoftware.es + * floppysoftware@gmail.com + */ + +/* STANDARD DEFs + ------------- +*/ + +#define BYTE unsigned char +#define WORD unsigned int +#define BOOL char +#define NULL 0 +#define TRUE 1 +#define FALSE 0 + +#define SIZEOF_CHAR 1 /* [unsigned] char */ +#define SIZEOF_INT 2 /* [unsigned] int */ +#define SIZEOF_PTR 2 /* pointer */ + +/* RUNTIME CODE + ------------ +*/ + +#ifndef CC_NO_ORG + +#asm +; Start at TPA + + ORG 0100H + +#endasm + +#endif + +#asm +; Runtime address + +ccrtadr: + +; Set stack under BDOS (xx00h) + + LD HL,(6) + LD L,0 + LD SP,HL + +; Leave space for stack and init. variables + + LD DE,ccSTACKSIZE + OR A + SBC HL,DE + DEC HL + LD (ccfreelast),HL + LD DE,ccfreemem + LD (ccfreefirst),DE + OR A + SBC HL,DE + INC HL + LD (ccfreebytes),HL + JR NC,ccargs + +; Error, no memory for stack + + LD C,9 + LD DE,ccerrstack + CALL 5 + JP 0 + +ccerrstack + DEFB 'Runtime Error - No stack$' + +; Setup command line arguments + +ccargs + +#endasm + +#ifndef CC_NO_ARGS + +#asm +; Copy command line + + LD HL,81H + LD DE,ccmdbuf + LD BC,127 + LDIR + + LD A,(80H) + LD B,0 + LD C,A + LD HL,ccmdbuf + ADD HL,BC + LD (HL),0 + +; Init. argc & argv + + LD DE,cchptr + LD HL,ccmdbuf - 1 + LD BC,1 +ccspc + INC HL + LD A,(HL) + OR A + JR Z,ccarg + CP ' ' + JR Z,ccspc + LD A,L + LD (DE),A + LD A,H + INC DE + LD (DE),A + INC DE + INC C +ccpar + INC HL + LD A,(HL) + OR A + JR Z,ccarg + CP ' ' + JR NZ,ccpar + LD (HL),0 + JR ccspc + +ccarg + LD HL,cchptr - 2 + PUSH BC ;argc + PUSH HL ;argv +#endasm + +#endif + +#ifdef CC_REDIR + +#asm + CALL redir ;FIXME - Check errors + POP DE + POP BC + PUSH HL ;argc + PUSH DE ;argv +#endasm + +#endif + +#asm + +; Execute program + + CALL main +#endasm + +/** + * @fn void exit(int code) + * @brief Exit to CP/M. + * + * FixMe: Return code is lost! + */ +#asm + +; Exit to CP/M + +exit + NOP ; Patch for atexit() -- 3 bytes. + NOP + NOP +#endasm + +#ifdef CC_STDIO + +BYTE *stdin, *stdout, *stderr; /* Sorry, no available FILE here */ + +#asm + LD HL,(stdin) + CALL ccflush + LD HL,(stdout) + CALL ccflush + + JP 0 + +ccflush + LD A,H + OR L + RET Z + PUSH HL + CALL fclose + POP BC + RET +#endasm + +#else + +#asm + JP 0 +#endasm + +#endif + +#asm + +; Variables for memory functions + +ccfreefirst + DEFW 0 ;Adr. first free byte +ccfreelast + DEFW 0 ;Adr. last free byte +ccfreebytes + DEFW 0 ;Number of free bytes + +#endasm + +#ifndef CC_NO_ARGS + +#asm +; Variables for command line arguments + +ccmdbuf + DEFS 128 ;Command line buffer + + DEFW ccNULL ;Pointers table for argv +cchptr + DEFW ccNULL,ccNULL,ccNULL,ccNULL,ccNULL + DEFW ccNULL,ccNULL,ccNULL,ccNULL,ccNULL + DEFW ccNULL,ccNULL,ccNULL,ccNULL,ccNULL + DEFW ccNULL,ccNULL,ccNULL,ccNULL,ccNULL + DEFW ccNULL,ccNULL,ccNULL,ccNULL,ccNULL + +ccNULL + DEFB 0 ;Null pointer +#endasm + +#endif + +#asm + +; Basic routines + +; Call formats to access locals: +; +; Format 1: CALL routine +; DEFB SpOffset +; +; Format 2: CALL routine +; DEFW SpOffset + +; HL = unsigned char from local (format 2) + +ccxgb2 + CALL ccladr2 + JR ccxgb3 + +; HL = unsigned char from local (format 1) + +ccxgb + CALL ccladr1 +ccxgb3 + LD L,(HL) + LD H,0 + RET + +; HL = signed char from local (format 2) + +ccxgc2 + CALL ccladr2 + JR ccgc + +; HL = signed char from local (format 1) + +ccxgc + CALL ccladr1 + +; HL = signed char from (HL) + +ccgc + LD A,(HL) + +; HL = signed char from A + +ccsxt + LD L,A + RLCA + SBC A + LD H,A + RET + +; LD H,0 +; LD L,A +; AND 128 +; RET Z +; DEC H +; RET + +; HL = word from local (format 2) + +ccxgw2 + CALL ccladr2 + JR ccgw + +; HL = word from local (format 1) + +ccxgw + CALL ccladr1 + +; HL = word from (HL) + +ccgw + LD A,(HL) + INC HL + LD H,(HL) + LD L,A + RET + +; char local = HL (format 2) + +ccxpb2 + CALL ccladr2sv + JR ccxpb3 + +; char local = HL (format 1) + +ccxpb + CALL ccladr1sv +ccxpb3 + LD DE,(cctmpw) + LD (HL),E + EX DE,HL + RET + +; int/ptr local = HL (format 2) + +ccxpw2 + CALL ccladr2sv + JR ccxpw3 + +; int/ptr local = HL (format 1) + +ccxpw + CALL ccladr1sv +ccxpw3 + LD DE,(cctmpw) + LD (HL),E + INC HL + LD (HL),D + EX DE,HL + RET + +; Copy 1 word from HL to (DE) + +ccpw + LD A,L + LD (DE),A + INC DE + LD A,H + LD (DE),A + RET + +; Calc. local adress + +cctmpw DEFW 0 + +ccladr2sv + LD (cctmpw),HL + +ccladr2 + POP DE + POP HL + LD C,(HL) + INC HL + LD B,(HL) + INC HL + PUSH HL + PUSH DE + LD HL,4 + ADD HL,BC + ADD HL,SP + RET + +ccladr1sv + LD (cctmpw),HL + +ccladr1 + POP DE + POP HL + LD B,0 + LD C,(HL) + INC HL + PUSH HL + PUSH DE + LD HL,4 + ADD HL,BC + ADD HL,SP + RET + +; OR HL = HL | DE + +ccor + LD A,L + OR E + LD L,A + LD A,H + OR D + LD H,A + RET + +; XOR HL = HL ^ DE + +ccxor + LD A,L + XOR E + LD L,A + LD A,H + XOR D + LD H,A + RET + +; AND HL = HL & DE + +ccand + LD A,L + AND E + LD L,A + LD A,H + AND D + LD H,A + RET + +; LOGIC OR HL = DE || HL + +cclgor + LD A,H + OR L + OR D + OR E + LD L,A + RET + + ;LD A,H + ;OR L + ;RET NZ + ;LD A,D + ;OR E + ;RET Z + ;INC L + ;RET + +; LOGIC AND HL = DE && HL + +cclgand + LD A,H + OR L + RET Z + LD A,D + OR E + RET NZ + JP ccfalse + +; HL = HL == DE + +cceq + OR A + SBC HL,DE + +; LOGIC NOT HL = !HL + +cclgnot + LD A,H + OR L + JP NZ,ccfalse + INC L + RET + +; HL = HL != DE + +ccne + OR A + SBC HL,DE + RET + +; HL = DE > HL (SIGNED) + +ccgt + EX DE,HL + +; HL = DE < HL (SIGNED) + +cclt + CALL cccmp + RET C + DEC L + RET + +; HL = DE <= HL (SIGNED) + +ccle + CALL cccmp + RET Z + RET C + DEC L + RET + +; HL = DE >= HL (SIGNED) + +ccge + CALL cccmp + RET NC + DEC L + RET + +; Compare DE with HL, and return: (SIGNED) +; +; CARRY if DE < HL +; ZERO if DE == HL +; HL = 1 + +cccmp + LD A,E + SUB L + LD E,A + LD A,D + SBC H + LD HL,1 + JP M,cccmp1 + OR E + RET + +cccmp1 + OR E + SCF + RET + +; HL = DE <= HL (UNSIGNED) + +ccule + CALL ccucmp + RET Z + RET C + DEC L + RET + +; HL = DE >= HL (UNSIGNED) + +ccuge + CALL ccucmp + RET NC + DEC L + RET + +; HL = DE > HL (UNSIGNED) + +ccugt + EX DE,HL + +; HL = DE < HL (UNSIGNED) + +ccult + CALL ccucmp + RET C + DEC L + RET + +; Compare DE with HL, and return: (UNSIGNED) +; +; CARRY if DE < HL +; ZERO if DE == HL +; HL = 1 + +ccucmp + LD A,D + CP H + JR NZ,ccucmp1 + LD A,E + CP L + +ccucmp1 + LD HL,1 + RET + +; HL = DE >> HL (UNSIGNED) + +ccuasr + EX DE,HL + LD A,E +ccuasr1 + OR A + RET Z + DEC A + SRL H + RR L + JR ccuasr1 + +; HL = DE >> HL (ARITMETIC) + +ccasr + EX DE,HL + LD A,E +ccasr1 + OR A + RET Z + DEC A + SRA H + RR L + JR ccasr1 + +; HL = DE << HL (UNSIGNED) + +ccuasl + +; HL = DE << HL (ARITMETIC) + +ccasl + EX DE,HL + LD A,E +ccasl1 + OR A + RET Z + DEC A + ADD HL,HL + JR ccasl1 + +; HL = DE - HL + +ccsub + EX DE,HL + OR A + SBC HL,DE + RET + +; HL = ~HL (1 COMPLEMENT) + +cccom + LD A,H + CPL + LD H,A + LD A,L + CPL + LD L,A + RET + +; HL = -HL (2 COMPLEMENT) + +ccneg + LD A,H + CPL + LD H,A + LD A,L + CPL + LD L,A + INC HL + RET + +#endasm + +#ifndef CC_NO_MUL + +#asm + +; HL = DE * HL (UNSIGNED) + +ccumul + +; HL = DE * HL (SIGNED) + +ccmul + LD A,H + LD C,L + LD HL,0 + LD B,16 +ccmul0 + ADD HL,HL + SLA C + RL A + JR NC,ccmul1 + ADD HL,DE +ccmul1 + DJNZ ccmul0 + RET + +#endasm + +#endif + +#ifndef CC_NO_DIV + +#asm + +; HL = DE % HL (SIGNED) + +ccmod + CALL ccdiv + EX DE,HL + RET + +; HL = DE / HL (SIGNED) +; DE = DE % HL (SIGNED) + +ccdiv + LD B,H + LD C,L + LD A,D + XOR B + PUSH AF + LD A,D + OR A + CALL M,ccdivdeneg + LD A,B + OR A + + JP P,ccdiv0 + + LD A,B + CPL + LD B,A + LD A,C + CPL + LD C,A + INC BC + +ccdiv0 + EX DE,HL + LD DE,0 + LD A,16 + +ccdiv1 + PUSH AF + + ADD HL,HL + + RL E + RL D + LD A,D + OR E + + JR Z,ccdiv2 + + LD A,E + SUB C + LD A,D + SBC B + + JP M,ccdiv2 + LD A,L + OR 1 + LD L,A + LD A,E + SUB C + LD E,A + LD A,D + SBC B + LD D,A + +ccdiv2 + POP AF + DEC A + JR NZ,ccdiv1 + POP AF + RET P + + CALL ccneg + +ccdivdeneg + LD A,D + CPL + LD D,A + LD A,E + CPL + LD E,A + INC DE + RET + +; HL = DE % HL (UNSIGNED) + +ccumod + CALL ccudiv + EX DE,HL + RET + +; HL = DE / HL (UNSIGNED) +; DE = DE % HL (UNSIGNED) + +ccudiv + LD (ccudiv_tmp),HL + LD HL,ccudiv_cnt + LD (HL),17 + LD BC,0 + PUSH BC + XOR A + +ccudiv0 + RL E + RL D + DEC (HL) + POP HL + JR Z,ccudiv2 + LD A,0 + ADC 0 + ADD HL,HL + LD B,H + ADD L + LD HL,(ccudiv_tmp) + SUB L + LD C,A + LD A,B + SBC H + LD B,A + PUSH BC + JR NC,ccudiv1 + ADD HL,BC + EX (SP),HL + +ccudiv1 + LD HL,ccudiv_cnt + CCF + JR ccudiv0 + +ccudiv2 + EX DE,HL + RET + +ccudiv_tmp + DEFW 0 +ccudiv_cnt + DEFB 0 + +#endasm + +#endif + +#ifndef CC_NO_SWITCH + +#asm + +; Switch, on entry: +; +; DE = Table address +; HL = Where to go if value was not found in table +; B = Number of entries in table + +ccswtch + EX (SP),HL + EX DE,HL + +ccswch1 + LD A,E + CP (HL) + INC HL + JR NZ,ccswch2 + LD A,D + CP (HL) + JR NZ,ccswch2 + INC HL + LD E,(HL) + INC HL + LD D,(HL) + EX DE,HL + POP BC + JP (HL) + +ccswch2 + INC HL + INC HL + INC HL + DJNZ ccswch1 + EX (SP),HL + POP BC + JP (HL) + +#endasm + +#endif + +#asm + +; HL = TRUE + +cctrue + LD L,1 + RET + +; HL = FALSE + +ccfalse + LD HL,0 + RET + +#endasm + + \ No newline at end of file diff --git a/Robots/mescc/printf.h b/Robots/mescc/printf.h new file mode 100644 index 0000000..60e9117 --- /dev/null +++ b/Robots/mescc/printf.h @@ -0,0 +1,94 @@ +/** + * @file printf.h + * @brief Library for printf() function. + * @author Miguel I. Garcia Lopez / FloppySoftware + * + * Implementation of printf() function, for MESCC (Mike's Enhanced + * Small C Compiler for Z80 & CP/M). + * + * Revisions: + * - 20 Oct 2000 : Last revision. + * - 16 Apr 2007 : GPL'd. + * - 25 Aug 2016 : Documented. GPL v3. + * + * Copyright (c) 1999-2016 Miguel I. Garcia Lopez / FloppySoftware. + * + * Licensed under the GNU General Public License v3. + * + * http://www.floppysoftware.es + * floppysoftware@gmail.com + */ +#ifndef PRINTF_H + +#define PRINTF_H + +// Dependencies +// ------------ + +#ifndef XPRINTF_H + #include +#endif + +#ifndef CONIO_H + #include +#endif + +/** + * @fn int printf(char *fmt, arg1, arg2, ...) + * @brief Formatted output to stdout (or console). + * + * See the documentation for xprintf.h to learn about the string format. + * + * @param fmt - string format + * @param arg1 - argument #1 + * @param arg? - argument #? + * @return number or characters written, or -1 on failure (currently always #). + */ +#asm + +printf: + ADD HL,HL + ADD HL,SP + INC HL + INC HL ;HL=Adr. fmt + + LD DE,xpfout + PUSH DE + LD DE,xpfend + PUSH DE + PUSH HL + + CALL xprintf + + POP BC + POP BC + POP BC + + RET +#endasm + +// int xpfout(char ch) : output ch to stdout; return 0 on success, !=0 on failure (currently always returns 0). + +#asm + +xpfout: + PUSH HL + CALL putchar + POP BC + LD HL,0 + RET + +#endasm + +// void xpfend(void) : end formatted output; currently does nothing. + +#asm + +xpfend: + RET + +#endasm + +#endif + + \ No newline at end of file diff --git a/Robots/mescc/string.h b/Robots/mescc/string.h new file mode 100644 index 0000000..0cca902 --- /dev/null +++ b/Robots/mescc/string.h @@ -0,0 +1,249 @@ +/** + * @file string.h + * @brief String functions. + * @author Miguel I. Garcia Lopez / FloppySoftware + * + * String functions, for MESCC (Mike's Enhanced + * Small C Compiler for Z80 & CP/M). + * + * Revisions: + * - 19 Mar 2001 : Last revision. + * - 16 Apr 2007 : GPL'd. + * - 15 Aug 2016 : Documented. GPL v3. + * + * Copyright (c) 1999-2016 Miguel I. Garcia Lopez / FloppySoftware. + * + * Licensed under the GNU General Public License v3. + * + * http://www.floppysoftware.es + * floppysoftware@gmail.com + */ +#ifndef STRING_H + +#define STRING_H + +/** + * @fn int strlen(char *str) + * @brief Return string length. + * @param str - string + * @return length in characters + */ +#asm +strlen: + LD D,H + LD E,L + LD BC,0FFFFH + XOR A + CPIR + OR A + SBC HL,DE + DEC HL + RET +#endasm + +/** + * @fn char *strcpy(char *dst, char *src) + * @brief Copy string. + * @param dst - destination string + * @param src - source string + * @return pointer to dst + */ +#asm +strcpy: + POP BC + POP HL + POP DE + PUSH DE + PUSH HL + PUSH BC + + PUSH DE + +strcpy2: + LD A,(HL) + LD (DE),A + INC HL + INC DE + OR A + JR NZ,strcpy2 + POP HL + RET +#endasm + +/** + * @fn char *strcat(char *dst, char *src) + * @brief Copy string at the end of another string. + * @param dst - destination string + * @param src - source string + * @return pointer to dst + */ +#asm +strcat: + POP BC + POP HL + POP DE + PUSH DE + PUSH HL + PUSH BC + + PUSH DE + +strcat2 + LD A,(DE) + OR A + JR Z,strcpy2 + INC DE + JR strcat2 +#endasm + +/** + * @fn int strcmp(char *str1, char *str2) + * @brief Compare two strings. + * @param str1 - a string + * @param str2 - a string + * @return <0 on str1 < str2; =0 on str1 == str2; >0 on str1 > str2 + */ +#asm +strcmp + POP BC + POP HL + POP DE + PUSH DE + PUSH HL + PUSH BC +strcmp1 + LD A,(DE) + CP (HL) + JR NZ,strcmp2 + + OR A + JR Z,strcmp2 + + INC DE + INC HL + JR strcmp1 + +strcmp2 + LD HL,0 + RET Z + JR NC,strcmp3 + DEC HL + RET +strcmp3 + INC L + RET +#endasm + +/** + * @fn char *strchr(char *str, char ch) + * @brief Search a character in a string. + * @param str - the string where to search + * @param ch - the character to find + * @return pointer to ch in the string, or NULL on failure + */ +#asm +strchr + POP BC + POP DE + POP HL + PUSH HL + PUSH DE + PUSH BC + + +strchr2 + LD A,(HL) + CP E + RET Z + + INC HL + OR A + JR NZ,strchr2 + + LD H,A + LD L,A + RET +#endasm + +/** + * @fn char *strupr(char *str) + * @brief Convert a string to upper case. + * @param str - a string + * @return pointer to str + */ +#asm +strupr + POP BC + POP HL + PUSH HL + PUSH BC + + PUSH HL + +strupr1 + LD A,(HL) + OR A + JR Z,strupr3 + + CP 'a' + JR C,strupr2 + CP 'z'+1 + JR NC,strupr2 + SUB 32 + LD (HL),A + +strupr2 + INC HL + JR strupr1 + +strupr3 + POP HL + RET +#endasm + +/** + * @fn int atoi(char *s) + * @brief Convert string to a integer. + * + * This function parses a string, interpreting its content as + * a decimal integer number, until the end of the string, or + * a non decimal digit: + * + * [+|-][[0..9]...][ZERO|NON_DECIMAL_DIGIT] + * + * Examples: + * - "-256" == -256 + * - "64" == 64 + * - "1024 bytes" == 1024 + * - "what?" == 0 + * + * @param s - a string + * @return integer value + */ +atoi(s) +char *s; +{ + int sign, val; + + if(*s == '+') + { + ++s; sign = 1; + } + else if(*s == '-') + { + ++s; sign = -1; + } + else + sign = 1; + + val=0; + + while(*s >= '0' && *s <= '9') + val = val * 10 + (*s++ - '0'); + + return val * sign; +} + +#endif + + \ No newline at end of file diff --git a/Robots/mescc/xprintf.h b/Robots/mescc/xprintf.h new file mode 100644 index 0000000..2a22a4b --- /dev/null +++ b/Robots/mescc/xprintf.h @@ -0,0 +1,365 @@ +/** + * @file xprintf.h + * @brief Support library for formatted output. + * @author Miguel I. Garcia Lopez / FloppySoftware + * + * Support library for formatted output, + * for MESCC (Mike's Enhanced Small C Compiler for Z80 & CP/M). + * + * All functions with formatted output like printf(), fprintf() + * and sprintf() call some private functions in this order: + * - pf_sf() + * - pf_s() + * - pf_out() + * + * Revisions: + * - 19 Mar 2001 : Last revision. + * - 16 Apr 2007 : GPL'd. + * - 09 Dec 2016 : Documented. Optimized. GPL v3. + * - 02 Aug 2017 : Output '%%' as '%'. + * + * Copyright (c) 1999-2016 Miguel I. Garcia Lopez / FloppySoftware. + * + * Licensed under the GNU General Public License v3. + * + * http://www.floppysoftware.es + * floppysoftware@gmail.com + */ +#ifndef XPRINTF_H + +#define XPRINTF_H + +// Dependencies +// ------------ + +#ifndef STRING_H + #include +#endif + +// Private globals +// --------------- + +BYTE xpf_err; // True on error + +extern WORD xpf_out; // Output function +extern WORD xpf_end; // End function + +int xpf_fw; // Field width +BYTE xpf_fa; // Field alignment: 0=left, 1=right +BYTE xpf_fz; // True on zero filling + +int xpf_cnt; // # of characters sent + +/** + * @fn int xprintf(WORD funout, WORD funend, WORD adrpars) + * @brief Formatted output. + * + * This function performs formatted output. It is used + * by printf(), fprintf() and sprintf() functions. + * + * The format is indicated in the string as follows: + * + * %[-][0][w]t + * + * | - : Left align (default: right align). + * | 0 : Zero filling on right align. + * | w : Width for alignment. If the specified width + * | is lower than the argument length, output is + * | done without aligment. Care with sprinf()! + * | t : d = Signed decimal integer. + * | u = Unsigned decimal integer. + * | x = Hexadecimal integer. + * | s = String. + * | c = Character. + * + * The pair %% outputs a single %. + * + * @param funout - function to output a character + * @param funend - function to end output + * @param adrpars - arguments addresses + * @return # of characters sent on sucess, -1 on failure + */ +xprintf(funout, funend, adrpars) +WORD funout, funend; +WORD *adrpars; +{ + WORD *parg; // Pointer to arguments + char *pfor; // Pointer to formatted string + int ivalue; + char ch; + + // Setup + xpf_out = funout; + xpf_end = funend; + + pfor = *adrpars; + parg = --adrpars; + + xpf_err = xpf_cnt = 0; + + // Loop + while((ch = *pfor++)) + { + if(ch == '%') + { + // Character % + if(*pfor == '%') + { + pf_out(ch); + ++pfor; + + continue; + } + + // Align + if(*pfor == '-') + { + xpf_fa = 0; // Left align + ++pfor; + } + else + xpf_fa = 1; // Right align + + // Zero filling + if(*pfor == '0') + { + xpf_fz = 1; // Zero filling + ++pfor; + } + else + xpf_fz = 0; + + // Width + xpf_fw = 0; + + while(*pfor >= '0' && *pfor <= '9') + xpf_fw = xpf_fw * 10 + (*pfor++) - '0'; + + // Type + switch(ch = *pfor++) + { + case 'd' : + ivalue = *parg--; + pf_dec(ivalue); + break; + case 'u' : + ivalue = *parg--; + pf_udec(ivalue); + break; + case 'x' : + ivalue = *parg--; + pf_hex(ivalue); + break; + case 'c' : + pf_cf(*parg--); + break; + case 's' : + pf_sf(*parg--); + break; + case '\0' : + --pfor; + // P'abajo + default : + pf_out('!'); + break; + } + } + else + pf_out(ch); + + if(xpf_err) + break; + } + + pf_end(); + + return xpf_err ? -1 : xpf_cnt; +} + +// void pf_sf(char *s) : output formatted string. + +pf_sf(s) +char *s; +{ + int len; + char fill; + + if(xpf_fw) + { + if((len = strlen(s)) < xpf_fw) + { + xpf_fw = xpf_fw-len; + + if(xpf_fa) + { + // Left align + fill = (xpf_fz ? '0' : ' '); + + while(xpf_fw--) + pf_out(fill); + pf_s(s); + } + else + { + // Right align + pf_s(s); + + while(xpf_fw--) + pf_out(' '); + } + + return; + } + } + + pf_s(s); +} + +// void pf_cf(char c) : output formatted character. + +pf_cf(c) +char c; +{ + char tmp[2]; + + tmp[0] = c; tmp[1] = '\0'; + + pf_sf(tmp); +} + +unsigned char xpf_dst[7]; // Buffer for numbers +unsigned char *xpf_dpt; // Buffer pointer + +// void pf_dec(int i) : output signed decimal integer. + +pf_dec(i) +int i; +{ + xpf_dpt = xpf_dst; + + if(i < 0) + { + *xpf_dpt++ = '-'; i = -i; + } + + pf_dec2(i); + + *xpf_dpt = '\0'; + + pf_sf(xpf_dst); +} + +// void pf_dec2(int i) : helper for pf_dec(). + +pf_dec2(i) +int i; +{ + int n; + + if(n = i / 10) + pf_dec2(n); + + *xpf_dpt++ = i % 10 + '0'; +} + +// void pf_udec(unsigned int i) : output unsigned decimal integer. + +pf_udec(i) +unsigned i; +{ + xpf_dpt = xpf_dst; + + pf_udec2(i); + + *xpf_dpt = '\0'; + + pf_sf(xpf_dst); +} + +// void pf_udec2(unsigned int i) : helper for pf_udec(). + +pf_udec2(i) +unsigned i; +{ + unsigned n; + + if(n = i / 10) + pf_udec2(n); + + *xpf_dpt++ = i % 10 + '0'; +} + +// void pf_hex(unsigned int i) : output hexadecimal integer. + +pf_hex(i) +unsigned i; +{ + xpf_dpt = xpf_dst; + + pf_hex2(i); + + *xpf_dpt = '\0'; + + pf_sf(xpf_dst); +} + +// void pf_hex2(unsigned int i) : helper for pf_hex(). + +pf_hex2(i) +unsigned i; +{ + unsigned n; + + if(n = i / 16) + pf_hex2(n); + + i %= 16; + + *xpf_dpt++ = i < 10 ? '0' + i : 'A' + i - 10; +} + +// void pf_s(char *s) : output string. + +pf_s(s) +char *s; +{ + while(*s) + pf_out(*s++); +} + +// void pf_out(char c) : output character. + +#asm +pf_out: + PUSH HL + DEFB 0CDH +xpf_out: + DEFW 0 + POP BC + + EX DE,HL + + LD HL,(xpf_cnt) + INC HL + LD (xpf_cnt),HL + + LD A,D + OR E + RET Z +;; LD A,255 + LD (xpf_err),A + RET +#endasm + +// void pf_end(void) : end output. + +#asm +pf_end: + DEFB 0C3H +xpf_end: + DEFW 0 +#endasm + +#endif + + \ No newline at end of file diff --git a/Robots/robots.c b/Robots/robots.c new file mode 100644 index 0000000..6a95aed --- /dev/null +++ b/Robots/robots.c @@ -0,0 +1,979 @@ +/* robots.c + + A turn-based game for CP/M-80 & CP/M-86. + + Based on ROBOTS, a BSD game (but no source code was taken from it). + + The objetive of the robots is only one: to kill you. + + The only thing you can do, is to try to escape from them. But use the + teletransportation with care: you have only a few teletransport tickets! + + The robots will die if they collide between them or crash against something. + + That's your only opportunity to win the robots. + + Good luck! + + Copyright (c) 2015 Miguel I. Garcia Lopez / FloppySoftware. + + A VT100 clear screen control code has been added by Anna Christina Naß + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + Contact: + + www.floppysoftware.vacau.com + cpm-connections.blogspot.com + floppysoftware@gmail.com + + Usage: + + robots + + Compile with MESCC (CP/M-80): + + cc robots + zsm robots + hextocom robots + + Compile with DR-C (CP/M-86): + + drc robots + link86 robots + + Compile with MESCC (SamaruX): + + cc robots + zmac robots.zsm --rel + link robots [op] + rename robots.x=robots.prl + + Changes: + + 18 Mar 2015 : 0.01 : Initial work from TinyWar source code. + 19 Mar 2015 : 1.00 : 1st version. + 09 Apr 2015 : 1.01 : Added support for SamaruX. +*/ + +/* TARGET: uncomment only one of following lines + --------------------------------------------- +*/ + +#define CPM80 +/* #define CPM86 */ +/* #define SAMARUX */ + +/* MESCC LIBRARIES + --------------- +*/ + +#ifdef CPM80 + +#define CC_NO_ARGS + +#include "mescc.h" +#include "conio.h" +#include "ctype.h" +#include "string.h" +#include "printf.h" + +#endif + +/* SAMARUX LIBRARIES + ----------------- +*/ + +#ifdef SAMARUX + +#include "samarux.h" + +#endif + +/* DR-C LIBRARIES & SUPPORT STUFF + ------------------------------ +*/ + +#ifdef CPM86 + +#include "stdio.h" + +#undef getchar + +/* DR-C doesn't have this one */ + +kbhit() +{ + return __BDOS(11, 0); +} + +/* DR-C doesn't work well mixing getchar() from STDIO.H + and our kbhit() */ + +getchar() +{ + return __BDOS(1, 0); +} + +/* DR-C doesn't have this one */ + +putstr(s) +char *s; +{ + while(*s) + putchar(*s++); +} + +/* DR-C has this one as a macro in CTYPE.H but cause + some problems with this code */ + +toupper(ch) +int ch; +{ + if(ch >= 'a' && ch <= 'z') + ch -= 32; + + return ch; +} + +#endif + +/* CLEAR SCREEN + ------------ +*/ + +ClrScr() +{ + printf("%c[2J%c[H", 27, 27); +} + +/* GAME DEFs & GLOBALS + ------------------- +*/ + +#define BOARD_ROWS 16 /* Board rows */ +#define BOARD_COLS 16 /* Board columns */ +#define BOARD_SIZE 256 /* Board cells = BOARD_ROWS * BOARD_COLS */ + +int brd_rows[BOARD_ROWS]; /* Board rows - char *brd_rows[] */ +char brd_cell[BOARD_SIZE]; /* Board cells */ + +#define ROBOTS_UNITS 8 /* # of robots */ + +int robots_left; /* Robots left in board */ + +int human_life; /* NZ if human is alive */ +int human_row; /* Row position */ +int human_col; /* Column position */ + +#define TELETR_UNITS 3 /* Teletransportation units */ + +int teltr_left; /* Teletransportation units left */ + +int moves; /* Number of moves done */ + +int random; /* Random number from 0 to 32767, managed by KbdIn() */ + +int running; /* NZ if we are playing, Z to quit */ + +int act_robots; /* NZ if robots can play */ + +char *brd_msg; /* Pointer to board message */ + +/* BOARD OBJECTS + ------------- +*/ + +#define TYPE_GROUND ' ' +#define TYPE_WALL 'X' +#define TYPE_ROBOT 'R' +#define TYPE_HUMAN 'H' +#define TYPE_DEAD 'D' +#define TYPE_SCRAP 'C' +#define TYPE_TEMP 'T' + +/* SPRITES + ------- +*/ + +#define SPR_GROUND " " +#define SPR_WALL "@@@" +#define SPR_HUMAN ".P." +#define SPR_DEAD "XPX" +#define SPR_SCRAP "X'X" + +#define SPR_ROBOT0 "/'\\" +#define SPR_ROBOT1 "/'|" +#define SPR_ROBOT2 "|'\\" +#define SPR_ROBOT3 "|'|" + +/* KEYS + ---- +*/ + +#define K_UP '8' +#define K_DOWN '2' +#define K_LEFT '4' +#define K_RIGHT '6' +#define K_UP_LEFT '7' +#define K_UP_RIGHT '9' +#define K_DOWN_LEFT '1' +#define K_DOWN_RIGHT '3' +#define K_TELETRANSP 'T' +#define K_STOP 'Q' + + +/* MAIN CODE + --------- +*/ + +main() +{ + ClrScr(); + + /* Show the banner, copyright info, etc. */ + + Banner(); + + /* Set up the board */ + + SetUpBoard(); + + /* Clean the board */ + + SetBoard(); + + /* We are playing! */ + + running = 1; + + /* Main loop */ + + while(human_life && robots_left && running) + { + ClrScr(); + + /* Show the board */ + + PrtLn(); + PrtBoard(); + PrtLn(); + + /* Robots should do their part */ + + act_robots = 1; + + /* Ask human for an action */ + + AskAction(); + + /* Robots should play too? */ + + if(act_robots) + ActRobots(); + } + + /* Game is over, check the reason and print a message */ + + if(!human_life) + Msg("You are dead, bad luck!"); + else if(!robots_left) + Msg("You win, congratulations!"); + else + Msg("Ok, I'm leaving! See you!"); + + /* Show the board for last time */ + + ClrScr(); + PrtLn(); + PrtBoard(); +} + +/* BANNER, COPYRIGHT, ETC. + ----------------------- +*/ + +Banner() +{ + /* Good looking banner */ + + puts("\n R () : : ()"); + puts(" R O B O T S \\ [0_0] /"); + puts(" B x-+-:-+-x"); + puts("R O B O T S |___|"); + puts(" T / \\"); + puts(" S \\ / v1.00\n"); + + /* Copyright and contact details */ + + puts("(c) 2015 Miguel Garcia / FloppySoftware"); + puts("www.floppysoftware.vacau.com"); + puts("cpm-connections.blogspot.com"); + puts("floppysoftware@gmail.com\n"); + + /* Waiting for the user */ + + putstr("Press any key to start... "); + + /* Wait a keyboard entry (this will be useful for random number generation) */ + + KbdIn(); + + /* New line */ + + PrtLn(); +} + +/* HUMAN ACTION + ------------ +*/ + +AskAction() +{ + int action; + + /* No board message */ + + Msg(NULL); + + /* Ask for action */ + + putstr("Action? "); + + /* Read keyboard */ + + action = KbdIn(); + + if(action != '\n') + PrtLn(); + + /* Do the action */ + + switch(action) + { + case K_UP : + ActMove(-1, 0); + break; + case K_DOWN : + ActMove(1, 0); + break; + case K_LEFT : + ActMove(0, -1); + break; + case K_RIGHT : + ActMove(0, 1); + break; + case K_UP_LEFT : + ActMove(-1, -1); + break; + case K_UP_RIGHT : + ActMove(-1, 1); + break; + case K_DOWN_LEFT : + ActMove(1, -1); + break; + case K_DOWN_RIGHT : + ActMove(1, 1); + break; + + case K_TELETRANSP : + ActTelTr(); + break; + + case K_STOP : + ActExit(); + break; + + default : + act_robots = 0; + break; + } +} + +/* ASK HUMAN FOR CONFIRMATION + -------------------------- +*/ + +AskConfirm() +{ + int reply; + + /* Prompt */ + + putstr("Confirm (Yes, No)? "); + + /* Read keyboard */ + + reply = KbdIn(); + + if(reply != '\n') + PrtLn(); + + /* Return TRUE or FALSE */ + + return reply == 'Y' ? 1 : 0; +} + +/* MOVE THE HUMAN + -------------- +*/ + +ActMove(srow, scol) +int srow, scol; +{ + int to_row, to_col, type; + + /* To where? */ + + to_row = human_row + srow; + to_col = human_col + scol; + + /* Act if next position is inside of board */ + + if(to_row >= 0 && to_row < BOARD_ROWS && to_col >= 0 && to_col < BOARD_COLS) + { + /* Check contents of new position */ + + type = GetCell(to_row, to_col); + + if(type == TYPE_GROUND) + { + /* GROUND: move human there */ + + SetCell(human_row, human_col, TYPE_GROUND); + + human_row = to_row; + human_col = to_col; + + SetCell(human_row, human_col, TYPE_HUMAN); + + /* Increment moves */ + + ++moves; + + /* Done */ + + return; + } + else if(type == TYPE_ROBOT) + { + /* ROBOT: human is dead */ + + --human_life; + + SetCell(human_row, human_col, TYPE_DEAD); + } + } + + /* Robots will do nothing */ + + act_robots = 0; +} + +/* TELETRANSPORTATION + ------------------ +*/ + +ActTelTr() +{ + int to_row, to_col; + + /* Do it if there are some teletransportations units */ + + if(teltr_left) + { + /* Find a random safe location */ + + do { + + to_row = random % BOARD_ROWS; + to_col = random % BOARD_COLS; + + random += 3; + + } while(GetCell(to_row, to_col) != TYPE_GROUND); + + /* Move the human there */ + + SetCell(human_row, human_col, TYPE_GROUND); + + human_row = to_row; + human_col = to_col; + + SetCell(human_row, human_col, TYPE_HUMAN); + + /* We lost a teletransportation unit */ + + --teltr_left; + + /* Increment moves */ + + ++moves; + } + + /* Robots will do nothing */ + + act_robots = 0; +} + +/* QUIT GAME + --------- +*/ + +ActExit() +{ + /* Ask for confirmation */ + + PrtLn(); + + running = !AskConfirm(); + + /* Robots will do nothing */ + + act_robots = 0; +} + + +/* MOVE ROBOTS + ----------- +*/ + +ActRobots() +{ + int row, col, to_row, to_col, type; + + /* Search robots in the board */ + + for(row = 0; row < BOARD_ROWS; ++row) + { + for(col = 0; col < BOARD_COLS; ++col) + { + /* Cell has a robot? */ + + if(GetCell(row, col) == TYPE_ROBOT) + { + /* Move near to the human */ + + to_row = row; + to_col = col; + + + /* Look for new row position */ + + if(row < human_row) + ++to_row; + else if(row > human_row) + --to_row; + + /* Look for new column position */ + + if(col < human_col) + ++to_col; + else if(col > human_col) + --to_col; + + /* Is there something there? */ + + type = GetCell(to_row, to_col); + + if(type == TYPE_GROUND) + { + /* GROUND: Move the robot there */ + + SetCell(row, col, TYPE_GROUND); + SetCell(to_row, to_col, TYPE_TEMP); + } + else + { + /* NOT GROUND: Robot is dead */ + + SetCell(row, col, TYPE_SCRAP); + + /* This robot is dead */ + + --robots_left; + + /* If there is the human or another robot + there, he is dead too */ + + if(type == TYPE_ROBOT || type == TYPE_TEMP) + { + /* Robot: dead */ + + SetCell(to_row, to_col, TYPE_SCRAP); + + --robots_left; + } + else if(type == TYPE_HUMAN) + { + /* Human: dead */ + + SetCell(to_row, to_col, TYPE_DEAD); + + --human_life; + } + } + } + } + } + + /* Persist the new locations of the robots */ + + for(row = 0; row < BOARD_ROWS; ++row) + { + for(col = 0; col < BOARD_COLS; ++col) + { + if(GetCell(row, col) == TYPE_TEMP) + SetCell(row, col, TYPE_ROBOT); + } + } +} + +/* SHOW THE BOARD + -------------- +*/ + +PrtBoard() +{ + int i, row, col, type; + + PrtBoardLn(); + + for(row = 0; row < BOARD_ROWS; ++row) + { + /* Left panel */ + + putchar('|'); + + for(col = 0; col < BOARD_COLS; ++col) + { + /* Get cell contents */ + + type = GetCell(row, col); + + /* Act according to the cell contents */ + + switch(type) + { + case TYPE_GROUND : + putstr(SPR_GROUND); + break; + + case TYPE_ROBOT : + switch(row & 0x03) + { + case 0 : putstr(SPR_ROBOT0); break; + case 1 : putstr(SPR_ROBOT1); break; + case 2 : putstr(SPR_ROBOT2); break; + case 3 : putstr(SPR_ROBOT3); break; + } + break; + + case TYPE_SCRAP : + putstr(SPR_SCRAP); + break; + + case TYPE_HUMAN : + putstr(SPR_HUMAN); + break; + + case TYPE_DEAD : + putstr(SPR_DEAD); + break; + + case TYPE_WALL : + putstr(SPR_WALL); + break; + } + } + + /* Right panel */ + + putchar('|'); + + switch(row) + { + case 1 : + putstr(" 7 8 9 "); + break; + case 2 : + putstr(" \\|/ "); + break; + case 3 : + putstr(" 4 --+-- 6 "); + break; + case 4 : + putstr(" /|\\ "); + break; + case 5 : + putstr(" 1 2 3 "); + break; + + case 7 : + putstr(" T:Teletran. "); + break; + case 8 : + putstr(" Q:Quit "); + break; + + case 12: + printf(" Teletr.: %2d ", teltr_left); + break; + case 13: + printf(" Moves: %4d ", moves); + break; + + case 10: + putstr("-------------"); + break; + + default : + putstr(" "); break; + } + + putchar('|'); + + PrtLn(); + } + + PrtBoardLn(); + + /* Show message */ + + putstr("| "); + + putstr(brd_msg); + + for(i = 3 * BOARD_COLS - strlen(brd_msg) - 1; i; --i) + putchar(' '); + + puts("| R O B O T S |"); + + PrtBoardLn(); +} + +/* PRINT BOARD LINE + ---------------- +*/ + +PrtBoardLn() +{ + int col; + + putchar('+'); + + for(col = 0; col < BOARD_COLS; ++col) + putstr("---"); + + puts("+-------------+"); +} + +/* PRINT NEW LINE + -------------- +*/ + +PrtLn() +{ + putchar('\n'); +} + +/* SET UP BOARD + ------------ +*/ + +SetUpBoard() +{ + int i; + + /* Set up the rows pointers */ + + for(i = 0; i < BOARD_ROWS; ++i) + brd_rows[i] = brd_cell + i * BOARD_COLS; +} + +/* CLEAR THE BOARD + --------------- +*/ + +ClearBoard() +{ + int row, col; + + /* Clear all cells */ + + for(row = 0; row < BOARD_ROWS; ++row) + for(col = 0; col < BOARD_COLS; ++col) + SetCell(row, col, TYPE_GROUND); +} + +/* SET CELL CONTENTS + ----------------- +*/ + +SetCell(row, col, type) +int row, col, type; +{ + char *p; + + /* Get the row pointer */ + + p = brd_rows[row]; + + /* Set the cell value */ + + p[col] = type; +} + +/* GET CELL CONTENTS + ----------------- +*/ + +GetCell(row, col) +int row, col; +{ + char *p; + + /* Get the row pointer */ + + p = brd_rows[row]; + + /* Set the cell value */ + + return p[col]; +} + +/* SET BOARD MESSAGE + ----------------- +*/ + +Msg(txt) +char *txt; +{ + brd_msg = txt == NULL ? "(c) 2015 FloppySoftware" : txt; +} + +/* SET BOARD CONTENTS + ------------------ +*/ + +SetBoard() +{ + int row, col, i, x; + char *pos; + + /* Clear message */ + + Msg(NULL); + + /* Clear board */ + + ClearBoard(); + + /* Reset some values */ + + moves = 0; + teltr_left = TELETR_UNITS; + + /* Set some walls */ + + SetCell(2, 2, TYPE_WALL); + SetCell(3, 2, TYPE_WALL); + SetCell(BOARD_ROWS - 4, BOARD_COLS - 3, TYPE_WALL); + SetCell(BOARD_ROWS - 3, BOARD_COLS - 3, TYPE_WALL); + + /* Set human values */ + + human_life = 1; + + human_row = BOARD_ROWS / 2; + human_col = BOARD_COLS / 2; + + SetCell(human_row, human_col, TYPE_HUMAN); + + /* Set robots values */ + + robots_left = ROBOTS_UNITS; + + /* Locate robots in random positions */ + + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + pos = "044E8AF2C5638EB229E936FAE5471EBB"; + + /* Get a number from 0 to 31 */ + + x = random % 32; + + i = 0; + + while(i < robots_left) + { + /* Get a position */ + + row = GetVal(pos[x++]) % BOARD_ROWS; if(x > 31) x = 0; + col = GetVal(pos[x++]) % BOARD_COLS; if(x > 31) x = 0; + + /* Place the robot there, if the location is empty */ + + if(GetCell(row, col) == TYPE_GROUND) + { + SetCell(row, col, TYPE_ROBOT); + + ++i; + } + } +} + +/* HELPER FOR SetBoard() + --------------------- +*/ + +GetVal(c) +int c; +{ + /* Return HEX value of digit */ + + if(c >= '0' && c <= '9') + return c - '0'; + + return c - 'A' + 10; +} + +/* GET CHARACTER FROM KEYBOARD AND SET RANDOM VALUE + ------------------------------------------------ +*/ + +KbdIn() +{ + /* Init random value */ + + random = 0; + + /* Wait for a key and increment the random value */ + + while(!kbhit()) + ++random; + + /* Set the random value to a legal one (0 ... 32767) */ + + random &= 0x7FFF; + + /* Return character */ + + return toupper(getchar()); +} + + + + diff --git a/Robots/robots.txt b/Robots/robots.txt new file mode 100644 index 0000000..91cc93e --- /dev/null +++ b/Robots/robots.txt @@ -0,0 +1,67 @@ +ROBOTS +------ + +A GAME FOR CP/M-80 & CP/M-86. + +v1.00 - 19 Mar 2015. + + R () : : () + R O B O T S \ [0_0] / + B x-+-:-+-x +R O B O T S |___| + T / \ + S \ / + +(c) 2015 Miguel Garcia / FloppySoftware + www.floppysoftware.es + cpm-connections.blogspot.com + floppysoftware@gmail.com + + +THE GAME +-------- + +Robots is a turn-based game for CP/M-80 & CP/M-86. + +Based on ROBOTS, a BSD game (but no source code was taken from it). + +The objetive of the robots is only one: to kill you. + +The only thing you can do, is to try to escape from them. But use the +teletransportation with care: you have only a few teletransport tickets! + +The robots will die if they collide between them or crash against something. + +That's your only opportunity to win the robots. + +Good luck! + + +GAME FILES +---------- + +ROBOTS .COM -- Game for CP/M-80. +ROBOTS .CMD -- Game for CP/M-86. +ROBOTS .C -- Source code for MESCC & DR-C. +ROBOTS .TXT -- This help file. +COPYING .TXT -- GNU General Public License. + + +TECHNICAL NOTES +--------------- + +This program was developed using MESCC (Mike's Enhanced Small C Compiler - my +own version of Small C) for the CP/M-80 version, and Digital Research C for +the CP/M-86 version. + +See ROBOTS.C for more details. + + +COPYRIGHT AND LEGAL NOTES +------------------------- + +This program is copyright of FLOPPY SOFTWARE from VALENCIA, SPAIN, and is +distributed under the GNU GENERAL PUBLIC LICENSE. + +Read the COPYING.TXT text file for more details. +