1
0

Added Robots

This commit is contained in:
acn 2020-03-10 16:16:14 +01:00
parent 0021b0387a
commit 1b9a8c9398
16 changed files with 3542 additions and 0 deletions

View File

@ -27,6 +27,7 @@ See this repository: https://git.imzadi.de/acn/backgammon-vt100
* [Sokoban](Sokoban/) * [Sokoban](Sokoban/)
* [Battleships](Battleships/) * [Battleships](Battleships/)
* [Blocks](Blocks/) * [Blocks](Blocks/)
* [Robots](Robots/)
## More Games on the Interwebs ## More Games on the Interwebs

48
Robots/README.md Normal file
View File

@ -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ß <acn@acn.wtf>.
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.

BIN
Robots/ROBOTS.COM Normal file

Binary file not shown.

339
Robots/copying.txt Normal file
View File

@ -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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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.
<signature of Ty Coon>, 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.

BIN
Robots/mescc/CC.COM Normal file

Binary file not shown.

BIN
Robots/mescc/CCOPT.COM Normal file

Binary file not shown.

BIN
Robots/mescc/HEXTOCOM.COM Normal file

Binary file not shown.

BIN
Robots/mescc/ZSM.COM Normal file

Binary file not shown.

252
Robots/mescc/conio.h Normal file
View File

@ -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


203
Robots/mescc/ctype.h Normal file
View File

@ -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


945
Robots/mescc/mescc.h Normal file
View File

@ -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


94
Robots/mescc/printf.h Normal file
View File

@ -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 <xprintf.h>
#endif
#ifndef CONIO_H
#include <conio.h>
#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


249
Robots/mescc/string.h Normal file
View File

@ -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


365
Robots/mescc/xprintf.h Normal file
View File

@ -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 <string.h>
#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


979
Robots/robots.c Normal file
View File

@ -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ß <acn@acn.wtf>
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());
}

67
Robots/robots.txt Normal file
View File

@ -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.