pax_global_header00006660000000000000000000000064147573723050014527gustar00rootroot0000000000000052 comment=862daab21ec97e6008b8241b75483cab0253370e crasm-1.11/000077500000000000000000000000001475737230500125565ustar00rootroot00000000000000crasm-1.11/.gitignore000066400000000000000000000000231475737230500145410ustar00rootroot00000000000000test/test_output/ crasm-1.11/COPYING000066400000000000000000000431051475737230500136140ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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. crasm-1.11/LICENSE000066400000000000000000000431771475737230500135770ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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 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. {description} Copyright (C) {year} {fullname} 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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) year 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 Lesser General Public License instead of this License. crasm-1.11/Makefile000066400000000000000000000005441475737230500142210ustar00rootroot00000000000000SHELL=/bin/sh MAKE=make prefix=/usr bindir=${prefix}/bin mandir=${prefix}/share/man all: ( cd src; ${MAKE} all ) clean: ( cd src; ${MAKE} clean ) ( cd test; ${MAKE} clean ) test: all ( cd test; ${MAKE} test ) install: cp src/crasm ${bindir}/crasm chmod 0755 ${bindir}/crasm cp crasm.1 ${mandir}/man1/crasm.1 chmod 0644 ${mandir}/man1/crasm.1 crasm-1.11/README.md000066400000000000000000000014661475737230500140440ustar00rootroot00000000000000# CRASM CRASM is a portable cross-assembler for the 6800, 6801, 6803, 6502, 65C02, and Z80. ## Documentation See the file [crasm.html](http://htmlpreview.github.io/?https://github.com/colinbourassa/crasm/blob/master/crasm.html). ## Changelog * crasm-1.8: Fixed incorrect 6800 opcode for BLE Fixed inconsistent handling of signedness for program counter variable * crasm-1.7: Fixed handling of extended ASCII characters in input files (Windows-specific) Fixed uninitialized memory in label array (was sometimes causing "too far branch" errors) * crasm-1.6: Fixed mishandled SUBD immediate (6801/6803) Fixed incorrect opcodes for MUL and RTI (6801/6803) Fixed documentation for DS pseudo Updated version number in page headers on output crasm-1.11/crasm.1000066400000000000000000000304561475737230500137550ustar00rootroot00000000000000.\" Copyright (C) 1987- Leon Bottou .\" .\" This is free documentation; 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. .\" .\" The GNU General Public License's references to "object code" .\" and "executables" are to be interpreted as the output of any .\" document formatting or typesetting system, including .\" intermediate and printed output. .\" .\" This manual 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 manual. Otherwise check the web site .\" of the Free Software Foundation at http://www.fsf.org. .\" .TH CRASM 1 "1/9/1987" "Crasm-1.3" "Crasm-1.3" .de SS .SH \\0\\0\\0\\$* .. .SH NAME crasm \- Cross assembler for 6800/6801/6803/6502/65C02/Z80 .SH SYNOPSIS .BI "crasm [-o " "codefile" "] [-slx] " "asmfile" Assemble the microprocessor program .I asmfile and produce output file .I codefile in Intel HEX or Motorola S Code format. A program listing and a symbol table are also produced on the standard output. The current version of .B crasm can assemble programs for the .BR 6800, .BR 6801, .BR 6803, .BR 6502, .BR 65C02, and .BR Z80 processors. The full list is printed when you invoke .B crasm without arguments. .SH OPTIONS .TP .BI "-o " codefile Specify the name of the output file. No output file is produced without this option. .TP .BI "-s" Disable warnings. .TP .BI "-l" Disable program listing output. .TP .BI "-x" Disable symbol table output. .PP .SH SYNTAX Each line of the assembly program should follow one of the following templates, where the brackets delimit optional parts. .IP "" .BI "[;" comment "]" .br .BI "" label " = " expression " [;" comment "]" .br .BI "[" label "] " mnemonic " " operand " [;" comment "]" .br .BI "" label "[;" comment "]" .PP Comments are introduced by a semicolon .BR "" "(" ";" ")" and extend to the end of the line. Labels are identifiers containing up to 36 alphanumeric characters (including period and underscore). Labels cannot start with a digit. Crasm does not usually pays attention to the column position of the line components. The only exception is the case of a line containing only a label and possibly a comment. In that case the label must start in column zero. .PP The format of the mnemonics and operands field depends on the selected micro-processor. A few mnemonics are valid for all processors and are used to give directives to the assembled. These are known as "pseudo-mnemonics". .SS Labels Labels are identifiers representing .br \(em an absolute address, .br \(em a relative address (position independent code), .br \(em a register, .br \(em a list of registers, .br \(em a specific bit at a specific address, .br \(em or a mnemonic. .PP Most labels are composed of at most 36 alphanumeric characters, periods .BR "" "(" "." ")" or underscores .BR "" "(" "_" ")." Labels cannot start with a digit. They are case insensitive. Labels starting with a period .BR "" "(" "." ")" are local labels whose scope is either limited to the macro in which they are defined, or to the code segment delimited by the pseudo-mnemonics .B CODE or .BR DUMMY . .PP The predefined "star" label .BR "" "(" "*" ")" represents the current program counter, that is to say, the address where the next assembly code instruction will be encoded. Other predefined labels include all pseudo-mnemonics, micro-processor specific mnemonics and register names. .SS Constants The assembled recognizes numerical constants expressed in decimal, hexadecimal, octal, binary, or ascii. .PP .TS center,box; lfB lfB lfB l l l l l l l l l l l l l l l l l l l l l l l l l l l . Type Format Examples = decimal \fIdddd \fB1234\fR,\fB 675\fR,\fB 12\fR,\fB 1\fR, but not \fB0.12\fR. = hexadecimal \fB$\fIdddd \fB$fd12\fR,\fB $2AC\fR,\fB $0\fR. \fIdddd\fBH\fR \fB03H\fR,\fB 2da7H\fR,\fB 0FC84H\fR, but not \fBFC84H\fR. \fB0X\fIdddd \fB0x03\fR,\fB 0x2AC\fR,\fB 0Xfc84\fR. = octal \fIdddd\fBQ\fR \fB377Q\fR,\fB 012412Q\fR. = binary \fB%\fIdddd \fB%01110110\fR,\fB %1100\fR. \fIdddd\fBB\fR \fB01110110B\fR,\fB 1100B\fR. \fB0B\fIdddd \fB0b1100\fR = ascii \fB'\fIcccc\fB'\fR \fB'a'\fR,\fB 'AB'\fR,\fB '"'\fR,\fB '\\n'\fR,\fB '\\''\fR. \fB"\fIcccc\fB"\fR \fB"\\t"\fR,\fB "\\""\fR,\fB "a'b"\fR. .TE .PP .SS Expressions Like labels, expressions can represent an absolute address .RI ( abs ), a relative address for position independent code .RI ( rel ), a register .RI ( reg ), or a list of registers .RI ( reglist ), or a reference to a specific bit at a specific address .RI ( bspec ). The following operators are recognized on expressions. .TS center,box; lfB lfB lfB l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l . Syntax Result Description = \fIabs\fB{\fIabs\fB}\fR \fIbspec\fR bit reference, e.g. \fBpia{3}\fR \fBADDR(\fIabs\fB)\fR \fIabs\fR address from a bit reference \fBBIT(\fIabs\fB)\fR \fIabs\fR bit number from a bit reference = \fB- \fIabs \fIabs\fR two's complement \fB~ \fIabs \fIabs\fR one's complement = \fIabs\fB << \fIabs\fR \fIabs\fR left shift \fIabs\fB >> \fIabs\fR \fIabs\fR right shift \fBHI(\fIabs\fB)\fR \fIabs\fR high byte ((abs>>8)&$ff) \fBLO(\fIabs\fB)\fR \fIabs\fR low byte (abs&$ff) = \fIabs\fB | \fIabs\fR \fIabs\fR bitwise or \fIabs\fB & \fIabs\fR \fIabs\fR bitwise and \fIabs\fB ^ \fIabs\fR \fIabs\fR bitwise xor = \fIabs\fB * \fIabs\fR \fIabs\fR multiplication \fIabs\fB * \fIabs\fR \fIabs\fR division = \fIabs\fB + \fIabs\fR \fIabs\fR addition \fIrel\fB + \fIabs\fR \fIrel\fR addition \fIabs\fB - \fIabs\fR \fIabs\fR subtraction \fIrel\fB - \fIabs\fR \fIrel\fR subtraction \fIrel\fB - \fIrel\fR \fIabs\fR subtraction = \fIreg\fB - \fIreg\fR \fIreglist\fR register range \fIreglist\fB \\ \fIreg\fR \fIreglist\fR register list .TE .PP The table lists operators in order of decreasing precedence. Parenthesis can be used to avoid ambiguities. A warning is generated when an entire expression is surrounded with parenthesis and can be confused with a micro-processor addressing mode. .PP Examples: .IP "" \fB (base+$12) >> 8 & 0xff00 \fR .br \fB 'A'-80H \fR .br \fB (base+0x12) \fR .PP The last example causes a warning because the parenthesis were not necessary and might suggest a micro-processor addressing mode. .PP All arithmetic expressions are evaluated on 32 bits. Arithmetic operations overflow silently. The arithmetic values are then truncated to the size implied by the micro-processor mnemonic. This truncation might cause a warning message. Examples: all the following instructions .IP "" (6502) \fBlda #$1234\fR .br (6800) \fBldaa $1234,x\fR .br (Z80) \fBld (ix+0C2H),b\fR .PP cause a warning .IP "" .B >>> WARNING: Operand overflow .PP However expression .IP "" .B $1123454 * 1298992 .PP overflows silently. .SS Pseudo-mnemonics The following pseudo-mnemonics are always recognized. .PP .BI "CPU " cpuname .in +7n Indicates the selected micro-processor type. This must appear before anu micro-processor specific instruction. The possible values of .I cpuname are listed when you invoke .B crasm without arguments. The current list includes .BR 6800, .BR 6801, .BR 6803, .BR 6502, .BR 65C02, and .BR Z80 .in -7n .PP .BI "OUTPUT " binformat .in +7n Indicates the format of the output file. Argument .I binformat can take values .B SCODE for producing an output file using Motorola's S code, or .B HEX for Intel's Hex format. The default depends on the selected micro-processor. .in -7n .PP .BI CODE .in +7n Delimit the scope of local labels and introduce a program section. .TP .BI DUMMY Delimit the scope of local labels and introduce a fake program section whose sole effect is to define labels without generating code. .in -7n .PP .BI "" label " EQU " expression .br .BI "" label " = " expression .in +7n Define the value of label .IR label . Labels defined using these directives can be redefined later in the program. .in -7n .PP .BI "[" label "] DB " expression "[,...," expression "]" .in +7n Insert the specified data bytes (8 bits). .in -7n .PP .BI "[" label "] DW " expression "[,...," expression "]" .in +7n Insert the specified data words (16 bits). The byte ordering depends on the selected micro-processor. .in -7n .PP .BI "[" label "] DL " expression "[,...," expression "]" .in +7n Insert the specified data longs (32 bits). The byte ordering depends on the selected micro-processor. .in -7n .PP .BI "[" label "] DDB " expression "[,...," expression "]" .in +7n Insert the specified double bytes (16 bits). The byte ordering is the opposite of the usual byte ordering for the selected micro-processor. .in -7n .PP .BI "[" label "] ASC " stringconstant .in +7n Insert the ascii representation of the string .I stringconstant . The string must be delimited by double quotes. The C escape sequences \fB\\r\fR, \fB\\n\fR, \fB\\t\fR, \fB\\0\fR, \fB\\'\fR, \fB\\"\fR, and \fB\\\\\fR are recognized. .in -7n .PP .BI "[" label "] DS " countexpr ",[" valexpr "]" .in +7n Insere .I countexpr bytes with value .IR valexpr . The default value is zero. .in -7n .PP .BI "[" label "] ALIGN EVEN" .br .BI "[" label "] ALIGN ODD" .in +7n Insert a null byte in order to make the program counter even or odd. .in -7n .PP .BI "IF [" expr1 " [" oper " " expr2 "]]" .br ... .br .BI "ELSE" .br ... .br .BI "ENDC" .in +7n Conditional assembly. The argument of .B IF can be empty, can be a single expression .BR expr1 , or can be two expressions separated by a comparison operator .BR > ", " < ", " >= ", " <= ", " == ", " != ", " = ", or " <> "." The assembler processes the lines located between the .B IF and the .BR ELSE pseudo-mnemonics if the comparison .I "expr1 oper expr2" is true or if the single expression .I expr1 is nonzero. Otherwise it processes the lines located between the .B ELSE and the .BR ENDC pseudo-mnemonics. Conditional assembly instructions can be nested. The .B ELSE part can be omitted. .in -7n .PP .BI "" "label" " MACRO" .br ... .br .BI " ENDM" .br .in +7n Define a new mnemonic .I label equivalent to all the instructions located between the .B MACRO and .B ENDM pseudo-mnemonics. Invocations of the macro can specify a list of comma separated operands. The character sequences \fB\\1\fR, \fB\\2\fR, ... \fB\\\fIN\fR in the macro definition are replaced by the supplied operands. The character sequence \fB\\#\fR is replaced by the number of supplied operands. The character sequence \fB\\*\fR is replaced by the unparsed macro arguments. .in -7n .PP .BI "EXITM" .in +7n This pseudo mnemonic can be used inside a macro definition to exit the macro. This is useful in conjunction with the conditional assembly pseudo-mnemonics. .in -7n .PP .BI "INCLUDE " filename .in +7n Force the assembler to process file named .I filename at the current point. .in -7n .PP .BR "LIST ON" .br .BR "LIST OFF" .in +7n Enable or disable the production of a listing (default is on.) .in -7n .PP .BR "CLIST ON" .br .BR "CLIST OFF" .in +7n Enable or disable the production of a listing for the non active branches of a conditional assembly construct (default is on.) .in -7n .PP .BR "ILIST ON" .br .BR "ILIST OFF" .in +7n Enable or disable the production of a listing for included files (default is off.) .in -7n .PP .BR "MLIST ON" .br .BR "MLIST OFF" .in +7n Enable or disable the production of a listing for the macro expansions (default is off.) .in -7n .PP .BR "NAM " title .in +7n Provide name .I title for the header of the listing pages. .in -7n .PP .BR "PAGE" .in +7n Start a new listing page. .in -7n .PP .BR "PAGE " lines "," columns .in +7n Specify the size of a listing page. .in -7n .PP .BR "SKIP " number .in +7n Skip .I number lines. .in -7n .PP .BR "FAIL " message .in +7n Generate an error message .IR message . .in -7n .PP .SH EXAMPLE .PP Here is a small 6502 program: .IP "" 2 \fB cpu 6502 .br cout = $fded ; display a character .br * = $300 ; assemble at $300 .br code .br pstring ldy #0 .br .1 lda message,y .br beq .2 .br jsr cout .br iny .br .2 bne .1 .br rts .br message asc "This is the message\0" .br code \fR .PP .SH CREDITS Leon Bottou, September 1987. crasm-1.11/crasm.html000066400000000000000000000403041475737230500145520ustar00rootroot00000000000000Manpage of CRASM

CRASM

Cross assembler for 6800/6801/6803/6502/65C02/Z80.

Summary   Download   Examples


 

SYNOPSIS

crasm [-o codefile] [-slx] asmfile

Assemble the microprocessor program asmfile and produce output file codefile in Intel HEX or Motorola S Code format. A program listing and a symbol table are also produced on the standard output. The current version of crasm can assemble programs for the 6800, 6801, 6803, 6502, 65C02, and Z80 processors. The full list is printed when you invoke crasm without arguments.

 

OPTIONS

-o codefile
Specify the name of the output file. No output file is produced without this option.
-s
Disable warnings.
-l
Disable program listing output.
-x
Disable symbol table output.

 

SYNTAX

Each line of the assembly program should follow one of the following templates, where the brackets delimit optional parts.

[;comment]
label = expression [;comment]
[label] mnemonic operand [;comment]

Comments are introduced by a semicolon (;) and extend to the end of the line. Labels are identifiers containing up to 36 alphanumeric characters (including period and underscore). Labels cannot start with a digit. The format of the mnemonics and operands field depends on the selected micro-processor. A few mnemonics are valid for all processors and are used to give directives to the assembled. These are known as "pseudo-mnemonics".

 

Labels

Labels are identifiers representing
- an absolute address,
- a relative address (position independent code),
- a register,
- a list of registers,
- a specific bit at a specific address,
- or a mnemonic.

Most labels are composed of at most 36 alphanumeric characters, periods (.) or underscores (_). Labels cannot start with a digit. They are case insensitive.

Labels starting with a period (.) are local labels whose scope is either limited to the macro in which they are defined, or to the code segment delimited by the pseudo-mnemonics CODE or DUMMY.

The predefined "star" label (*) represents the current program counter, that is to say, the address where the next assembly code instruction will be encoded. Other predefined labels include all pseudo-mnemonics, micro-processor specific mnemonics and register names.

 

Constants

The assembled recognizes numerical constants expressed in decimal, hexadecimal, octal, binary, or ascii.

TypeFormatExamples
decimaldddd1234, 675, 12, 1, but not 0.12.
hexadecimal$dddd$fd12, $2AC, $0.
ddddH03H, 2da7H, 0FC84H, but not FC84H.
0Xdddd0x03, 0x2AC, 0Xfc84.
octalddddQ377Q, 012412Q.
binary%dddd%01110110, %1100.
ddddB01110110B, 1100B.
0Bdddd0b1100
ascii'cccc''a', 'AB', '"', '\n', '\''.
"cccc""a", "AB", "'", "\n", "\"".

 

Expressions

Like labels, expressions can represent an absolute address (abs), a relative address for position independent code (rel), a register (reg), or a list of registers (reglist), or a reference to a specific bit at a specific address (bspec).

The following operators are recognized on expressions.

SyntaxResultDescription
abs{abs}bspecbit reference, e.g. pia{3}
ADDR(bspec)absaddress from a bit reference
BIT(bspec)absbit number from a bit reference
absabstwo's complement
absabsone's complement
abs << absabsleft shift
abs >> absabsright shift
abs | absabsbitwise or
abs & absabsbitwise and
abs ^ absabsbitwise xor
abs * absabsmultiplication
abs * absabsdivision
abs + absabsaddition
rel + absreladdition
abs - absabssubtraction
rel - absrelsubtraction
rel - relrelsubtraction
reg - regreglistregister range
reglist \ regreglistregister list construction

The table lists operators in order of decreasing precedence. Parenthesis can be used to avoid ambiguities. A warning is generated when an entire expression is surrounded with parenthesis and can be confused with a micro-processor addressing mode.

Examples:

(base+$12) >> 8 & 0xff00
'A'-80H
(base+0x12)

The last example causes a warning because the parenthesis were not necessary and might suggest a micro-processor addressing mode.

All arithmetic expressions are evaluated on 32 bits. Arithmetic operations overflow silently. The arithmetic values are then truncated to the size implied by the micro-processor mnemonic. This truncation might cause a warning message.

Examples: all the following instructions

(6502) lda #$1234
(6800) ldaa $1234,x
(Z80)  ld (ix+0C2H),b

cause a warning

>>> WARNING: Operand overflow

However expression

$1123454 * 1298992

overflows silently.

 

Pseudo-mnemonics

The following pseudo-mnemonics are always recognized.

CPU cpuname
Indicates the selected micro-processor type. This must appear before anu micro-processor specific instruction. The possible values of cpuname are listed when you invoke crasm without arguments. The current list includes 6800, 6801, 6803, 6502, 65C02, and Z80

OUTPUT binformat
Indicates the format of the output file. Argument binformat can take values SCODE for producing an output file using Motorola's S code, or HEX for Intel's Hex format. The default depends on the selected micro-processor.

CODE
Delimit the scope of local labels and introduce a program section.

DUMMY
Delimit the scope of local labels and introduce a fake program section whose sole effect is to define labels without generating code.

label EQU expression
label = expression
Define the value of label label. Labels defined using these directives can be redefined later in the program.

[label] DB expression[,...,expression]
Insert the specified data bytes (8 bits).

[label] DW expression[,...,expression]
Insert the specified data words (16 bits). The byte ordering depends on the selected micro-processor.

[label] DL expression[,...,expression]
Insert the specified data longs (32 bits). The byte ordering depends on the selected micro-processor.

[label] DDB expression[,...,expression]
Insert the specified double bytes (16 bits). The byte ordering is the opposite of the usual byte ordering for the selected micro-processor.

[label] ASC stringconstant
Insert the ascii representation of the string stringconstant . The string must be delimited by double quotes. The C escape sequences \r, \n, \t, \0, \', \", and \\ are recognized.

[label] DS countexpr,[valexpr]
Insere countexpr bytes with value valexpr. The default value is zero.

[label] ALIGN EVEN
[label] ALIGN ODD
Insert a null byte in order to make the program counter even or odd.

IF condexpr
 ...
ELSE
 ...
ENDC
Conditional assembly: A conditional expression condexpr is either a single expression (see above), or two expressions separated by a comparison operator: == or = tests whether the two expressions are equal, <> tests that they are not equal, <=, >=, <, and > perform comparison tests. If expression condexpr is true or non zero, the assembler processes the lines located between the IF and the ELSE pseudo-mnemonics. Otherwise it processes the lines located between the ELSE and the ENDC pseudo-mnemonics. Conditional assembly instructions can be nested. The ELSE part can be omitted.

label MACRO
        ...
ENDM
Define a new mnemonic label equivalent to all the instructions located between the MACRO and ENDM pseudo-mnemonics. Invocations of the macro can specify a list of comma separated operands. The character sequences \1, \2, ... \N in the macro definition are replaced by the supplied operands. The character sequence \0 is replaced by the number of supplied operands.

EXITM
This pseudo mnemonic can be used inside a macro definition to exit the macro. This is useful in conjunction with the conditional assembly pseudo-mnemonics.

INCLUDE filename
Force the assembler to process file named filename at the current point.

LIST ON
LIST OFF
Enable or disable the production of a listing (default is on.)

CLIST ON
CLIST OFF
Enable or disable the production of a listing for the non active branches of a conditional assembly construct (default is on.)

ILIST ON
ILIST OFF
Enable or disable the production of a listing for included files (default is off.)

MLIST ON
MLIST OFF
Enable or disable the production of a listing for the macro expansions (default is off.)

NAM title
Provide name title for the header of the listing pages.

PAGE
Start a new listing page.

PAGE rows,columns
Specify the size of a listing page.

SKIP number
Skip number lines.

FAIL message
Generate an error message message.

 

EXAMPLE

Here is a small 6502 program:

              cpu 6502
          cout = $fded ; display a character
             * = $300  ; assemble at $300
               code
          pstring  ldy #0
          .1       lda message,y
                   beq .2
                   jsr cout
                   iny
          .2       bne .1
                   rts
          message  asc "This is the message "
               code

Assembling this program gives the following listing:

Crasm LYB 1.3:                                                   page  1

                         1
                         2              cpu 6502
  FDED                   3            cout = $fded ; display a character
  0300                   4               * = $300  ; assemble at $300
                         5                 code
0300 A000                6            pstring  ldy #0
0302 B90E03              7            .1       lda message,y
0305 E004                8                     beq .2
0307 20EDFD              9                     jsr cout
030A C8                 10                     iny
030B D0F5               11            .2       bne .1
030D 60                 12                     rts
030E 54686973206973
0315 20746865206D65
031C 737361676500       13            message  asc "This is the message\0"
                        14                 code
                        15

ERRORS:       0
WARNINGS:     0

Successful assembly...
 Last address      321 (801)
 Code length        44 (68)



Crasm LYB 1.3:                                                   page  2

 FDED   Abs COUT
^030E   Abs MESSAGE
?0300   Abs PSTRING
and the following S Code file:
S1130300A000B90E03E00420EDFDC8D0F5605468E8
S1130310697320697320746865206D657373616700
S1050320650072
S9030000FC
 

CREDITS

Leon Bottou, September 1987.


 

Index

SYNOPSIS
OPTIONS
SYNTAX
Labels
Constants
Expressions
Pseudo-mnemonics
EXAMPLE
CREDITS
crasm-1.11/crasm.spec000077500000000000000000000012421475737230500145410ustar00rootroot00000000000000Name: crasm Summary: Cross assembler for 6800/6801/6803/6502/65C02/Z80. Version: 1.4 Release: 1 License: GPL Group: Applications/Internet URL: http://crasm.sourceforge.net/ Source0: %{name}-%{version}.tar.gz Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root %description Crasm is a cross assembler for 6800/6801/6803/6502/65C02/Z80. It produces binaries in Intel HEX or Motorola S Code. %prep %setup -q %build make %install rm -fr %{buildroot} install -d %{buildroot}%{_bindir} install -d %{buildroot}%{_mandir}/man1 %makeinstall %clean rm -fr %{buildroot} %files %defattr(-,root,root) %{_bindir}/* %{_mandir}/* %doc crasm.html %doc test %changelog crasm-1.11/src/000077500000000000000000000000001475737230500133455ustar00rootroot00000000000000crasm-1.11/src/.gitignore000066400000000000000000000000121475737230500153260ustar00rootroot00000000000000crasm *.o crasm-1.11/src/Makefile000066400000000000000000000007261475737230500150120ustar00rootroot00000000000000SHELL =/bin/sh CFLAGS = -O -Wall -std=c89 LDFLAGS = LIBS = -lm RM = rm OBJ = crasm.o stdvocabulary.o pseudos.o macro.o label.o \ parse.o filter.o operator.o output.o xref.o scode.o CPU = cpulist.o cpu6800.o cpu6502.o cpuz80.o all: crasm crasm: $(OBJ) $(CPU) ${CC} ${CFLAGS} ${LDFLAGS} -o crasm $(OBJ) $(CPU) ${LIBS} @echo "done" clean: FORCE -${RM} 2>/dev/null *.o crasm FORCE: .PHONY: FORCE $(OBJ): dcl.h label.h $(CPU): cpu.h crasm-1.11/src/cpu.h000066400000000000000000000034531475737230500143120ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* CRASM: cpu.h include pour les fichiers de definition de CPU */ #ifndef CPU_H #define CPU_H #include "dcl.h" #include "label.h" /***************************************************************************/ #define startmnemos(n) struct label n[] = { #define endmnemos {(void*)-1,(void*)-1,{0},0,0,0,0,0} }; #define mnemo(n,c,p) {0,0,n,NOREDEF,L_MNEMO,p,c,0}, #define directive(n,c) {0,0,n,NOREDEF|NOLABEL,L_MNEMO,0,c,0}, #define address(n,a) {0,0,n,NOREDEF,L_ABSOLUTE,0,a,0}, #define directbit(n,a,b) {0,0,n,NOREDEF,L_DIRECTBIT,b,a,0}, #define regs(n,r) {0,0,n,NOREDEF,L_REGS,r,0,(1<>8) & 0xf ]) #define m2_base (code & 0xff) static int cpuflag; /* relative branchs */ static int branch(int code, char* label, char* mnemo, char* oper) { byte d; int dd; extern unsigned long pc; struct result* r; r = parse(oper); /* operand search */ checktype(r, L_ABSOLUTE); /* is it a number? */ dd = r->value - pc - 2; /* displacement calc */ d = dd; /* -> signed byte */ insert8(code); /* generate code */ insert8(dd); if (d != dd) /* test operand after: */ { crasm_error("too long branch"); /* if an error occurs during */ } return 0; /* the first pass, branch is */ } /* always too bytes long */ /* IMPORTANT: * * You had better generate code before signaling errors about * * the operand values. So the first pass calculates right * * forward references even when a ghost error occurs. */ static int single(int code, char* label, char* mnemo, char* oper) /* single byte instructions */ { insert8(code); if (oper) /* no operand! */ { crasm_error("no operands allowed"); } return 0; } /* addressing modes description */ static struct addmodes { char* filter; short num; } addmodes[] = { { "(_?_,_X_)", 0,}, /* indirect pre-indexed */ { "@_?_,_X", 0,}, /* special syntax */ { "(_?_)_,_Y", 2,}, /* indirect post-indexed */ { "@_?_,_Y", 2,}, { "(_?_)", 4,}, /* indirect */ { "@_?", 4,}, { "_", 14,}, /* implicit */ { "#_?", 12,}, /* immediate */ { "?_,_X", 6,}, /* indexed by x */ { "?_,_Y", 8,}, /* indexed by y */ { "?", 10,}, /* direct or register */ { NULL,} }; /* add 1 to mode for 16bits operands */ /* mode 1 and 4 are 65c02 specific */ /* offsettable by type */ static unsigned char offsettable[][16] = { /* (.,x) (.),y (.) .,x .,y . #. _ (..,x) (..),y (..) ..,x ..,y .. #.. A */ {0x01, 0x00, 0x11, 0x00, 0x12, 0x00, 0x15, 0x1d, 0x00, 0x19, 0x05, 0x0d, 0x09, 0x00, 0x00, 0x00,}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x1e, 0x16, 0x1e, 0x06, 0x0e, 0x02, 0x00, 0x00, 0x0a,}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x16, 0x00, 0x06, 0x0e, 0x00, 0x00, 0x00, 0x00,}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x1e, 0x00, 0x00, 0x06, 0x0e, 0x6b, 0x00, 0x00, 0x3a,}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x1e, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00, 0x00, 0x7a,}, {0x00, 0x7c, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00,}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x9e, 0x00, 0x00, 0x64, 0x9c, 0x00, 0x00, 0x00, 0x00,}, }; /* 0: ora and eor adc lda cmp sbc (noimm):sta 1: (noimm|noindy):asl,rol,lsr,ror (noacc|noindx|noindy):cpx,cpy (noacc|noindx):ldx (noacc|noindy):ldy 2: (noindx)stx (noindy):sty 3: (noimm):inc (noacc):bit { INC A and DEC A are too } 4: (noimm):dec (noacc|noindx):tsb,trb { strange to group together } 5: jmp { modes: ABS (ABS) (ABS,X) } 6: jsr { only ABS } 7: stz { very strange opcodes for ZP ABS ZP,X ABS,X } */ static int standard(int code, char* label, char* mnemo, char* oper) { register int mode; register int opcode; char* toparse; int value = 0; /* search mode */ if (!oper) { mode = 14; } else { register struct addmodes* q; for (q = addmodes; q->filter; q++) { if (filter(oper, q->filter, &toparse)) { break; } } if (! q->filter) { crasm_error("unknown addressing mode"); } mode = q->num; } /* special case */ if (((code & F_noacc) && mode >= 14) || ((code & F_noimm) && mode == 12) || ((code & F_noindx) && mode == 6) || ((code & F_noindy) && mode == 8)) { crasm_error("illegal addressing mode"); } /* extract value */ if (mode < 14) { register struct result* r; r = parse(toparse); if (mode == 10 && r->type == L_REGS && r->modifier == 0) { mode = 15; } else { checktype(r, L_ABSOLUTE); } value = r->value; if ((value & 0xFF00) || (r->flags & FORWARD)) { if (mode != 12) { mode |= 1; } else if (value & 0xFF00) { crasm_warning("operand overflow"); } } } /* generate opcode */ { register int offset; if (!(offset = m2_offset[mode])) /* if not found */ { mode |= 1; /* test long version */ } if (!(offset = m2_offset[mode])) { crasm_error("illegal addressing mode"); } insert8(opcode = (m2_base + offset) & 0xFF); } /* generate operand */ if (mode < 14) { if (mode & 1) { insert16(value); } else { insert8(value); } } /* test specials modes */ if (cpuflag < 1) { if (code == (0x60 | 0x100 | F_noimm | F_noindy)) { crasm_error("no ROR instruction on 6500"); } } if (cpuflag < 2) { if (mode == 4 || opcode == 0x7c || opcode == 0x89 || opcode == 0x1a || opcode == 0x3a) { crasm_error("illegal use of 65C02 addressing mode"); } } return 0; } startmnemos(m6502) /* 6502 mnemonics */ mnemo("bpl", branch, 0x10) /* branchs */ mnemo("bmi", branch, 0x30) mnemo("bvc", branch, 0x50) mnemo("bvs", branch, 0x70) mnemo("bcc", branch, 0x90) mnemo("bcs", branch, 0xb0) mnemo("bne", branch, 0xd0) mnemo("beq", branch, 0xf0) /* pseudos branchs */ mnemo("bhi", branch, 0xb0) /* A>=M unsigned */ mnemo("blo", branch, 0x90) /* A< M unsigned */ mnemo("bgt", branch, 0x10) /* A>=M signed */ mnemo("ble", branch, 0x30) /* A< M signed */ mnemo("nop", single, 0xea) /* single byte instructions */ mnemo("brk", single, 0x00) mnemo("rti", single, 0x40) mnemo("rts", single, 0x60) mnemo("pha", single, 0x48) mnemo("pla", single, 0x68) mnemo("php", single, 0x08) mnemo("plp", single, 0x28) mnemo("dex", single, 0xca) mnemo("dey", single, 0x88) mnemo("inx", single, 0xe8) mnemo("iny", single, 0xc8) mnemo("tsx", single, 0xba) mnemo("txs", single, 0x9a) mnemo("tax", single, 0xaa) mnemo("txa", single, 0x8a) mnemo("tay", single, 0xa8) mnemo("tya", single, 0x98) mnemo("clc", single, 0x18) mnemo("clv", single, 0xb8) mnemo("cli", single, 0x58) mnemo("cld", single, 0xd8) mnemo("sec", single, 0x38) mnemo("sei", single, 0x78) mnemo("sed", single, 0xf8) mnemo2("ora", 0, 0x00, 0) mnemo2("and", 0, 0x20, 0) mnemo2("eor", 0, 0x40, 0) mnemo2("adc", 0, 0x60, 0) mnemo2("sta", 0, 0x80, F_noimm) mnemo2("lda", 0, 0xa0, 0) mnemo2("cmp", 0, 0xc0, 0) mnemo2("sbc", 0, 0xe0, 0) mnemo2("asl", 1, 0x00, F_noimm | F_noindy) mnemo2("rol", 1, 0x20, F_noimm | F_noindy) mnemo2("lsr", 1, 0x40, F_noimm | F_noindy) mnemo2("ror", 1, 0x60, F_noimm | F_noindy) mnemo2("ldx", 1, 0xa0, F_noacc | F_noindx) mnemo2("ldy", 1, 0x9e, F_noacc | F_noindy) mnemo2("cpx", 1, 0xde, F_noindy | F_noindx | F_noacc) mnemo2("cpy", 1, 0xbe, F_noindy | F_noindx | F_noacc) mnemo2("stx", 2, 0x80, F_noindx) mnemo2("sty", 2, 0x7e, F_noindy) mnemo2("inc", 3, 0xe0, F_noimm) mnemo2("bit", 3, 0x1e, F_noacc) mnemo2("dec", 4, 0xc0, F_noimm) mnemo2("jmp", 5, 0x00, 0) mnemo2("jsr", 6, 0x00, 0) regs("a", 0) /* 6502 registers. */ regs("x", 1) /* for register mode ops as */ regs("y", 2) /* ASL A, ROL A etc.. */ regs("p", 3) regs("s", 4) endmnemos startmnemos(m65c02) mnemo("phx", single, 0xda) /* 65c02 special mnemonics */ mnemo("plx", single, 0xfa) mnemo("phy", single, 0x5a) mnemo("ply", single, 0x7a) mnemo("bra", branch, 0x80) mnemo2("stz", 7, 0x00, 0) mnemo2("tsb", 4, 0xfe, F_noacc | F_noindx) mnemo2("trb", 4, 0x0e, F_noacc | F_noindx) endmnemos void init6502(int code) { cpuflag = code; setflag(F_ADDR16); /* 16 bits address */ setflag(F_LOHI); /* LSB first */ clrflag(F_RELATIF); /* no translatable code */ bindvocabulary(m6502); /* add 6502 mnemos */ if (code == 2) { bindvocabulary(m65c02); /* add 65c02 mnemos if needed */ } } crasm-1.11/src/cpu6800.c000066400000000000000000000214041475737230500146170ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* 6800, 6802, 6808, 6801, 6803 */ #include "cpu.h" /* relative branchs */ static int branch(int code, char* label, char* mnemo, char* oper) { byte d; int dd; extern unsigned long pc; struct result* r; r = parse(oper); /* operand search */ checktype(r, L_ABSOLUTE); /* is it a number? */ dd = r->value - pc - 2; /* displacement calc */ d = dd; /* -> signed byte */ insert8(code); /* generate code */ insert8(dd); if (d != dd) /* test operand after: */ { crasm_error("too long branch"); /* if an error occurs during */ } /* the first pass, branch is */ return 0; /* always too bytes long */ } /* IMPORTANT: * * You had better generate code before signaling errors about * * the operand values. So the first pass calculates right * * forward references even when a ghost error occurs. */ /* single byte instructions */ static int single(int code, char* label, char* mnemo, char* oper) { insert8(code); if (oper) /* no operand! */ { crasm_error("no operands allowed"); } return 0; } /* addressing modes filters */ static struct addmodes { char* filt; /* and code shifts */ int add; } addmodes[] = { { "#_?", 0x00,}, { ",_x", 0x20,}, { "?_,_x", 0x20,}, { "?", 0x30,}, { NULL } }; /* test operands */ static int findmode(char* oper, int* pvalue) /* value -> *pvalue and */ /* if it isn't a forward */ { /* reference, try direct */ register struct addmodes* q; /* addressing */ register struct result* r; char* address; address = "0"; for (q = addmodes; q->filt ; q++) { if (oper && filter(oper, q->filt, &address)) { r = parse(address); checktype(r, L_ABSOLUTE); *pvalue = r->value; if (q->add == 0x30) { if (!(r->flags & FORWARD) && !(r->value & 0xff00)) { return 0x10; } } return q->add; } } crasm_error("Unknown addressing mode"); return 0; } /* generate code, given base */ static void codemode(int code, int add, int value) /* opcode, addressing mode */ { /* shift and operand value */ insert8(code + add); if (!add && /* 16 bits immediate */ (code == 0x8c || code == 0x8e || code == 0xc3 || code == 0xcc || code == 0xce || code == 0x83)) { insert16(value); } else if (add == 0x30) /* extended */ { insert16(value); } else { insert8(value); /* direct, indexed and */ if (value & 0xff00) /* 8 bits immediate */ { if (add == 0x20) { crasm_error("too long displacement"); } else { crasm_warning("operand overflow"); } } } } /* all addressing modes */ static int standard(int code, char* label, char* mnemo, char* oper) { register int add; int value; add = findmode(oper, &value); codemode(code, add, value); return 0; } /* all but immediate */ static int standard2(int code, char* label, char* mnemo, char* oper) { register int add; int value; add = findmode(oper, &value); codemode(code, add, value); if (add == 0) /* immediate -> error */ { crasm_error("Bad addressing mode"); } return 0; } /* only indexed and extended */ static int standard3(int code, char* label, char* mnemo, char* oper) { register int add; int value; add = findmode(oper, &value); if (add == 0x10) { add = 0x30; /* direct -> extended */ } codemode(code, add, value); if (add <= 0x10) /* immediate -> error */ { crasm_error("Bad addressing mode"); } return 0; } /* 6800 mnemonics */ startmnemos(m6800) mnemo("bra", branch, 0x20) /* branches */ mnemo("bsr", branch, 0x8d) mnemo("bhi", branch, 0x22) mnemo("bls", branch, 0x23) mnemo("bcc", branch, 0x24) mnemo("bcs", branch, 0x25) mnemo("bne", branch, 0x26) mnemo("beq", branch, 0x27) mnemo("bvc", branch, 0x28) mnemo("bvs", branch, 0x29) mnemo("bpl", branch, 0x2a) mnemo("bmi", branch, 0x2b) mnemo("bge", branch, 0x2c) mnemo("blt", branch, 0x2d) mnemo("bgt", branch, 0x2e) mnemo("ble", branch, 0x2f) mnemo("nop", single, 0x01) /* single byte instructions */ mnemo("rti", single, 0x3b) mnemo("rts", single, 0x39) mnemo("swi", single, 0x3f) mnemo("wai", single, 0x3e) mnemo("aba", single, 0x1b) mnemo("clra", single, 0x4f) mnemo("clrb", single, 0x5f) mnemo("cba", single, 0x11) mnemo("coma", single, 0x43) mnemo("comb", single, 0x53) mnemo("nega", single, 0x40) mnemo("negb", single, 0x50) mnemo("daa", single, 0x19) mnemo("deca", single, 0x4a) mnemo("decb", single, 0x5a) mnemo("inca", single, 0x4c) mnemo("incb", single, 0x5c) mnemo("psha", single, 0x36) mnemo("pshb", single, 0x37) mnemo("pula", single, 0x32) mnemo("pulb", single, 0x33) mnemo("rola", single, 0x49) mnemo("rolb", single, 0x59) mnemo("rora", single, 0x46) mnemo("rorb", single, 0x56) mnemo("asla", single, 0x48) mnemo("aslb", single, 0x58) mnemo("asra", single, 0x47) mnemo("asrb", single, 0x57) mnemo("lsra", single, 0x44) mnemo("lsrb", single, 0x54) mnemo("sba", single, 0x10) mnemo("tab", single, 0x16) mnemo("tba", single, 0x17) mnemo("tsta", single, 0x4d) mnemo("tstb", single, 0x5d) mnemo("dex", single, 0x09) mnemo("des", single, 0x34) mnemo("inx", single, 0x08) mnemo("ins", single, 0x31) mnemo("tsx", single, 0x30) mnemo("txs", single, 0x35) mnemo("clc", single, 0x0c) mnemo("clv", single, 0x0a) mnemo("cli", single, 0x0e) mnemo("sec", single, 0x0d) mnemo("sev", single, 0x0b) mnemo("sei", single, 0x0f) mnemo("tap", single, 0x06) mnemo("tpa", single, 0x07) mnemo("neg", standard3, 0x40) /* memory instructions */ mnemo("com", standard3, 0x43) mnemo("lsr", standard3, 0x44) mnemo("ror", standard3, 0x46) mnemo("asr", standard3, 0x47) mnemo("asl", standard3, 0x48) mnemo("rol", standard3, 0x49) mnemo("dec", standard3, 0x4a) mnemo("inc", standard3, 0x4c) mnemo("tst", standard3, 0x4d) mnemo("jmp", standard3, 0x4e) mnemo("clr", standard3, 0x4f) mnemo("suba", standard, 0x80) /* accumulator & memory */ mnemo("cmpa", standard, 0x81) /* instructions */ mnemo("sbca", standard, 0x82) mnemo("anda", standard, 0x84) mnemo("bita", standard, 0x85) mnemo("ldaa", standard, 0x86) mnemo("staa", standard2, 0x87) /* store instructions are */ mnemo("eora", standard, 0x88) /* never immediate */ mnemo("adca", standard, 0x89) mnemo("oraa", standard, 0x8a) mnemo("adda", standard, 0x8b) mnemo("cpx", standard, 0x8c) mnemo("jsr", standard3, 0x8d) mnemo("lds", standard, 0x8e) mnemo("sts", standard2, 0x8f) mnemo("subb", standard, 0xc0) mnemo("cmpb", standard, 0xc1) mnemo("sbcb", standard, 0xc2) mnemo("andb", standard, 0xc4) mnemo("bitb", standard, 0xc5) mnemo("ldab", standard, 0xc6) mnemo("stab", standard2, 0xc7) mnemo("eorb", standard, 0xc8) mnemo("adcb", standard, 0xc9) mnemo("orab", standard, 0xca) mnemo("addb", standard, 0xcb) mnemo("ldx", standard, 0xce) mnemo("stx", standard2, 0xcf) endmnemos startmnemos(m6801) mnemo("lsrd", single, 0x04) /* 6801 special mnemonics */ mnemo("asld", single, 0x05) mnemo("brn", branch, 0x21) mnemo("pulx", single, 0x38) mnemo("abx", single, 0x3a) mnemo("pshx", single, 0x3c) mnemo("mul", single, 0x3d) mnemo("subd", standard, 0x83) mnemo("addd", standard, 0xc3) mnemo("ldd", standard, 0xcc) mnemo("std", standard2, 0xcd) endmnemos void init6800(int code) { setflag(F_ADDR16); /* 16 bit address */ clrflag(F_LOHI); /* MSB first */ clrflag(F_RELATIF); /* no translatable code */ bindvocabulary(m6800); /* add 6800 mnemos */ if (code == 1) { bindvocabulary(m6801); /* add 6801 mnemos if needed */ } } crasm-1.11/src/cpulist.c000066400000000000000000000030551475737230500151770ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* Liste des CPUs connus */ #include "cpu.h" extern void init6800(int code); extern void init6502(int code); extern void initz80(int code); startcpu newcpu("6800", init6800, 0) /* Motorola 8 bit family father */ newcpu("6801", init6800, 1) /* 6800+rom+I/Os+16bits ALU */ newcpu("6803", init6800, 1) /* ROMless 6801 */ newcpu("6500", init6502, 0) /* First 6502 procs, without ROR */ newcpu("6502", init6502, 1) /* Standard 6502 (Apple,Cbm..) */ newcpu("65C02", init6502, 2) /* CMOS 6502, ext. instr. set */ newcpu("Z80", initz80, 0) /* 8080 revisited */ endcpu crasm-1.11/src/cpuz80.c000066400000000000000000000412421475737230500146450ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* Z80 */ #include "cpu.h" static int offset, offsetflag, indexflag; static int arg, arg8flag, arg16flag; #define isreg8(n) (n>=0 && n<8) /* registres a 8 bits */ #define isreg16(n) (n>=8 && n<16) /* registres a 16 bits */ #define isspecialreg(b) (n>=16) /* registres speciaux */ #define IX 0xdd #define IY 0xfd #define HL 0xff #define ACCUMULATOR 7 #define MREGISTER 6 #define HLREGISTER 10 #define MEMORY -1 #define IMDATA -2 #define SPBC -4 #define SPDE -5 #define CLRALL indexflag=offsetflag=arg8flag=arg16flag=0 static char* needreg8 = "operates with reg8 or (HL),(IX+nn),(IY+nn)"; static char* needacc = "operates on A only"; static char* badop = "illegal addressing mode"; /* GETREG prend un registre ou un mode d'addressage */ static char* indexed[] = { "(_IX_)", "(_IY_)", "(_IX_+_?_)", "(_IY_+_?_)", "(_IX_-_?_)", "(_IY_-_?_)" }; static int getreg(char* oper) { register struct result* r; register int i; char* oper2; for (i = 0; i < 6; i++) { if (filter(oper, indexed[i], &oper2)) { offset = 0; if (i > 1) { r = parse(oper2); checktype(r, L_ABSOLUTE); offset = r->value; if (i > 3) { offset = -offset; } } if (indexflag || offsetflag) { crasm_error(badop); } offsetflag = TRUE; indexflag = i & 1 ? IY : IX; return MREGISTER; } } if (filter(oper, "(_HL_)")) { if (indexflag && indexflag != HL) { crasm_error(badop); } indexflag = HL; return MREGISTER; } if (filter(oper, "(_BC_)")) { return SPBC; } if (filter(oper, "(_DE_)")) { return SPDE; } if (filter(oper, "(_?_)", &oper2)) { r = parse(oper2); checktype(r, L_ABSOLUTE); if (arg8flag || arg16flag) { crasm_error(badop); } arg16flag = TRUE; arg = r->value; return MEMORY; } r = parse(oper); if (r->type == L_ABSOLUTE) { if (arg8flag || arg16flag) { crasm_error(badop); } arg16flag = TRUE; arg = r->value; return IMDATA; } checktype(r, L_REGS); if (r->value != (1 << r->modifier)) { crasm_error("illegal register list"); } if (r->modifier == 12 || r->modifier == 13 || r->modifier == HLREGISTER) { switch (r->modifier) { case 12: i = IX; break; case 13: i = IY; break; default: i = HL; break; } if (indexflag && indexflag != i) { crasm_error(badop); } indexflag = i; return HLREGISTER; } return r->modifier; } static int docode(int code) { if (indexflag == IX || indexflag == IY || offsetflag) { insert8(indexflag); } if (code & 0xff00) { insert8(code >> 8); } else { insert8(code); } if (offsetflag) { insert8(offset); if (offset != (byte) offset) { crasm_warning("offset overflow"); } } if (code & 0xff00) { insert8(code); } if (arg8flag) { insert8(arg); if (arg & 0xff00) { crasm_warning("argument overflow"); } } else if (arg16flag) { insert16(arg); } return 0; } /* relative branchs */ static int relbranch(int code, char* label, char* mnemo, char* oper) { byte d; int dd; extern unsigned long pc; struct result* r; r = parse(oper); /* operand search */ checktype(r, L_ABSOLUTE); /* is it a number? */ dd = r->value - pc - 2; /* displacement calc */ d = dd; /* -> signed byte */ insert8(code); /* generate code */ insert8(dd); if (d != dd) /* test operand after */ { crasm_error("too long branch"); /* if an error occurs during */ } return 0; /* the first pass, branch is */ } /* always too bytes long */ /* IMPORTANT: * * You had better generate code before signaling errors about * * the operand values. So the first pass calculates right * * forward references even when a ghost error occurs. */ /* simple instruction */ static int simple(int code, char* label, char* mnemo, char* oper) { if (code & 0xff00) { insert8(code >> 8); } insert8(code); if (oper) /* no operand! */ { crasm_error("no operands allowed"); } return 0; } static int im(int code, char* label, char* mnemo, char* oper) { register struct result* r; r = parse(oper); checktype(r, L_ABSOLUTE); switch (r->value) { case 0: insert16(0x46ed); break; case 1: insert16(0x56ed); break; case 2: insert16(0x5eed); break; default: insert16(0); crasm_error("Bad interruption mode"); } return 0; } static int rst(int code, char* label, char* mnemo, char* oper) { register struct result* r; r = parse(oper); checktype(r, L_ABSOLUTE); if (!(r->value & 0xfff8)) { r->value <<= 3; } insert8(0xc7 | r->value); if (r->value & 0xffc7) { crasm_error("Bad RST vector"); } return 0; } static char* condcodes[] = { "NZ", "Z", "NC", "C", "PO", "PE", "P", "M", NULL }; static int searchcond(int maxcond, char* oper, char** pres) { register char** q; char* ccode; if (filter(oper, "?_,_?", &ccode, pres)) { for (q = condcodes; maxcond--; q++) { if (filter(ccode, *q)) { return q - condcodes; } } crasm_error("Bad condition code"); } *pres = oper; return -1; } static int jr(int code, char* label, char* mnemo, char* oper) { char* operand2; code = 0x20 + (searchcond(4, oper, &operand2) << 3); return relbranch(code, label, mnemo, operand2); } static int ret(int code, char* label, char* mnemo, char* oper) { register char** q; if (!oper || !*oper) { insert8(0xc9); } else { for (q = condcodes; *q; q++) { if (filter(oper, *q)) { insert8(0xc0 + ((q - condcodes) << 3)); return 0; } } crasm_error("Bad condition code"); } return 0; } static int call(int code, char* label, char* mnemo, char* oper) { char* operand2; register int cond; register struct result* r; cond = searchcond(8, oper, &operand2) << 3; r = parse(operand2); checktype(r, L_ABSOLUTE); if (cond >= 0) { insert8(0xc4 + cond); } else { insert8(0xcd); } insert16(r->value); return 0; } static int jp(int code, char* label, char* mnemo, char* oper) { char* operand2; register int cond; register struct result* r; CLRALL; if (filter(oper, "(_?_)", &operand2)) { if (getreg(operand2) == HLREGISTER) { docode(0xe9); } else { crasm_error("illegal indirection"); } } else { cond = searchcond(8, oper, &operand2) << 3; r = parse(operand2); checktype(r, L_ABSOLUTE); if (cond >= 0) { insert8(0xc2 + cond); } else { insert8(0xc3); } insert16(r->value); } return 0; } static int ex(int code, char* label, char* mnemo, char* oper) { char* oper2; CLRALL; if (filter(oper, "DE_,_HL") || filter(oper, "HL_,_DE")) { return docode(0xeb); } if (filter(oper, "(_SP_)_,_?", &oper2) || filter(oper, "?_,_(_SP_)", &oper2)) { if (getreg(oper2) == HLREGISTER) { return docode(0xe3); } } /* EX AF,AF' ' is a special filter char. So, if there is one in OPER, then OPER is OPER+SPACES+REMARK... We have to manage with */ if (filter(oper, "AF_,_AF'_?", &oper2) || filter(oper, "AF'_,_AF_?", &oper2)) { if (oper2 == NULL || !*oper2 || *oper2 == ';') { return docode(0x08); } } crasm_error("Illegal EX instruction"); return 0; } static int inout(int code, char* label, char* mnemo, char* oper) { char* op1; char* op2; register int reg; CLRALL; if ((!(code & 8)) ? filter(oper, "(?)_,_?", &op1, &op2) : filter(oper, "?_,_(?)", &op2, &op1)) { reg = getreg(op1); if (reg == IMDATA) { reg = getreg(op2); if (reg != ACCUMULATOR) { crasm_error(needacc); } arg8flag = TRUE; docode(code); } else if (reg == 1) { reg = getreg(op2); if (!isreg8(reg) || reg == 6) { crasm_error("operates on reg8 only"); } reg <<= 3; if (!(code & 8)) { reg += 1; } docode(0xed40 + reg); } else { crasm_error("port is (C) or (nn)"); } } else { crasm_error(badop); } return 0; } static int bitop(int code, char* label, char* mnemo, char* oper) { register struct result* r; char* oper1; char* oper2; register int bit; register int reg; CLRALL; if (!filter(oper, "?_,_?", &oper1, &oper2)) { crasm_error("two operands required"); } r = parse(oper1); checktype(r, L_ABSOLUTE); bit = r->value; if (bit < 0 || bit > 7) { crasm_error("illegal bit number"); } reg = getreg(oper2); if (! isreg8(reg)) { crasm_error(needreg8); } docode(code + reg + (bit << 3)); return 0; } static int onreg8(int code, char* label, char* mnemo, char* oper) { register int reg; CLRALL; reg = getreg(oper); if (!isreg8(reg)) { crasm_error(needreg8); } return docode(code + reg); } static int logical(int code, char* label, char* mnemo, char* oper) { register int reg; char* op1; char* op2; CLRALL; if (filter(oper, "?_,_?", &op1, &op2)) { if (getreg(op1) != ACCUMULATOR) { crasm_error(needacc); } oper = op2; crasm_warning("One operand only. but i understand!"); } reg = getreg(oper); if (reg == IMDATA) { reg = 0x46; arg8flag = TRUE; } return docode(code + reg); } static int stackop(int code, char* label, char* mnemo, char* oper) { register int reg; CLRALL; reg = getreg(oper); if (reg == 19) { reg = 11; } else if (reg == 11) { reg = 19; } if (!isreg16(reg)) { crasm_error("Operates with AF,BC,DE,HL,IX,IY"); } return docode(code + (reg << 4)); } static int arith(int code, char* label, char* mnemo, char* oper) { register int reg; char* op1; char* op2; CLRALL; if (!filter(oper, "?_,_?", &op1, &op2)) { crasm_error(badop); } reg = getreg(op1); if (reg == ACCUMULATOR) { logical(code, label, mnemo, op2); } else if (reg == HLREGISTER) { if (indexflag != HL && code != 0x80) { crasm_error("illegal index operation"); } switch (code) { case 0x80: code = 0x09 - 0x80; break; case 0x88: code = 0xed4a - 0x80; break; case 0x98: code = 0xed42 - 0x80; break; } reg = getreg(op2); if (!isreg16(reg)) { crasm_error(badop); } docode(code + (reg << 4)); } else { crasm_error(badop); } return 0; } static int incr(int code, char* label, char* mnemo, char* oper) { register int reg; CLRALL; reg = getreg(oper); if (isreg8(reg)) { code >>= 8; docode((reg << 3) + code); } else if (isreg16(reg)) { code &= 0xff; reg -= 8; docode(code + (reg << 4)); } else { crasm_error(badop); } return 0; } static int ld(int code, char* label, char* mnemo, char* oper) { register int reg1; register int reg2; char* op1; char* op2; if (!filter(oper, "?_,_?", &op1, &op2)) { crasm_error(badop); } CLRALL; reg1 = getreg(op1); reg2 = getreg(op2); if (isreg8(reg1)) { if (isreg8(reg2)) { if (reg1 == reg2 && reg1 == MREGISTER) { crasm_error(badop); } return docode(0x40 + (reg1 << 3) + reg2); } if (reg2 == IMDATA) { arg8flag = TRUE; return docode(0x06 + (reg1 << 3)); } if (reg1 == ACCUMULATOR) { if (reg2 == MEMORY) { return docode(0x3a); } if (reg2 == SPBC) { return docode(0x0a); } if (reg2 == SPDE) { return docode(0x1a); } if (reg2 == 17) { return docode(0xed57); } if (reg2 == 18) { return docode(0xed5f); } } } if (isreg16(reg1)) { if (reg2 == IMDATA) { return docode(0x01 + ((reg1 - 8) << 4)); } if (reg2 == MEMORY) { if (reg1 == HLREGISTER) { return docode(0x2a); } else { return docode(0xed4b + ((reg1 - 8) << 4)); } } if (reg2 == HLREGISTER && reg1 == 11) { return docode(0xf9); } } if (reg1 == MEMORY) { if (reg2 == ACCUMULATOR) { return docode(0x32); } if (reg2 == HLREGISTER) { return docode(0x22); } if (isreg16(reg2)) { return docode(0xed43 + ((reg2 - 8) << 4)); } } if (reg2 == ACCUMULATOR) { if (reg1 == SPBC) { return docode(0x02); } if (reg1 == SPDE) { return docode(0x12); } if (reg1 == 17) { return docode(0xed47); } if (reg1 == 18) { return docode(0xed4f); } } crasm_error(badop); return 0; } startmnemos(mz80) /* Z80 mnemonics */ regs("a", 7) /* registers */ regs("b", 0) regs("c", 1) regs("d", 2) regs("e", 3) regs("h", 4) regs("l", 5) regs("bc", 8) regs("de", 9) regs("hl", 10) regs("sp", 11) regs("ix", 12) regs("iy", 13) regs("f", 16) regs("i", 17) regs("r", 18) regs("af", 19) mnemo("ccf", simple, 0x3f) /* instructions without oper */ mnemo("cpd", simple, 0xeda9) mnemo("cpdr", simple, 0xed89) mnemo("cpi", simple, 0xeda1) mnemo("cpir", simple, 0xedb1) mnemo("cpl", simple, 0x2f) mnemo("daa", simple, 0x27) mnemo("exx", simple, 0xd9) mnemo("halt", simple, 0x76) mnemo("ind", simple, 0xedaa) mnemo("indr", simple, 0xedba) mnemo("ini", simple, 0xeda2) mnemo("inir", simple, 0xedb2) mnemo("di", simple, 0xf3) mnemo("ei", simple, 0xfb) mnemo("ldd", simple, 0xeda8) mnemo("lddr", simple, 0xedb8) mnemo("ldi", simple, 0xeda0) mnemo("ldir", simple, 0xedb0) mnemo("neg", simple, 0xed44) mnemo("nop", simple, 0x00) mnemo("otdr", simple, 0xedbb) mnemo("otir", simple, 0xedb3) mnemo("outd", simple, 0xedab) mnemo("outi", simple, 0xeda3) mnemo("reti", simple, 0xed4d) mnemo("retn", simple, 0xed45) mnemo("rla", simple, 0x17) mnemo("rlca", simple, 0x07) mnemo("rld", simple, 0xed6f) mnemo("rra", simple, 0x1f) mnemo("rrca", simple, 0x0f) mnemo("rrd", simple, 0xed67) mnemo("scf", simple, 0x37) mnemo("im", im, 0) /* Specials */ mnemo("rst", rst, 0) mnemo("djnz", relbranch,0x10) mnemo("jr", jr, 0) mnemo("jp", jp, 0) mnemo("call", call, 0) mnemo("ret", ret, 0) mnemo("ex", ex, 0) mnemo("in", inout, 0xdb) mnemo("out", inout, 0xd3) mnemo("bit", bitop, 0xcb40) /* Quasi regulars */ mnemo("set", bitop, 0xcbc0) mnemo("res", bitop, 0xcb80) mnemo("sla", onreg8, 0xcb20) mnemo("sra", onreg8, 0xcb28) mnemo("srl", onreg8, 0xcb38) mnemo("rl", onreg8, 0xcb10) mnemo("rr", onreg8, 0xcb18) mnemo("rlc", onreg8, 0xcb00) mnemo("rrc", onreg8, 0xcb08) mnemo("or", logical, 0xb0) mnemo("and", logical, 0xa0) mnemo("xor", logical, 0xa8) mnemo("sub", logical, 0x90) mnemo("cp", logical, 0xb8) mnemo("push", stackop, 0xc5 - 0x80) mnemo("pop", stackop, 0xc1 - 0x80) mnemo("adc", arith, 0x88) /* no index */ mnemo("sbc", arith, 0x98) /* no index */ mnemo("add", arith, 0x80) /* index ok */ mnemo("inc", incr, 0x0403) /* (*8) */ mnemo("dec", incr, 0x050b) mnemo("ld", ld, 0) /* heavy magic !! */ endmnemos void initz80(int code) { setflag(F_CODE_HEX); /* Intel hex by default */ setflag(F_ADDR16); /* 16 bits address */ setflag(F_LOHI); /* LSB first */ clrflag(F_RELATIF); /* no translatable code */ bindvocabulary(mz80); /* add Z80 mnemos */ } crasm-1.11/src/crasm.c000066400000000000000000000250721475737230500146240ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* CRASM: crasm.c noyau central LYB 9/87 */ #include "dcl.h" #include "version.h" #include "label.h" #define SCODE 1 #define LIST 2 #define XREF 4 #define WARN 8 #define INPUT 128 extern struct label* searchlabel(char* name); extern struct label pseudos[]; jmp_buf errorjump; int errnumber; int warnnumber; int segment; extern int includelevel; extern int thiscall; struct label* starlabel; int llen; int ppos; int plen; int lpos; int linenumber; char lineprefix; char* filename; char* scodename; char curline[256]; FILE* file; FILE* scode; int asmflags; int passnumber; int macrolevel; int advance; void jmp_buf_copy(jmp_buf out, jmp_buf in) { #ifdef JBUFSIZE int i; for (i = 0; i < JBUFSIZE; i++) { out[i] = in[i]; } #else memcpy(out, in, sizeof(jmp_buf)); #endif } int main(int argc, char** argv) { int flags; char* s; passnumber = 0; flags = LIST | WARN; #ifdef DEBUG flags |= XREF; #endif if (argc == 0) { crasm_fatal("NOT from WB"); } while (--argc) { if (**(++argv) == '-') { for (s = (*argv) + 1; *s; s++) { switch (*s) { case 's': /* suppress warnings */ flags &= ~WARN; break; case 'l': /* suppress listing */ flags &= ~LIST; break; case 'x': /* force XREF */ flags |= XREF; break; case 'o': /* output name */ if (!s[1] && argc > 1 && !(flags & SCODE)) { flags |= SCODE; scodename = *++argv; --argc; } break; default: syntax("Bad Option(s)"); } } } else { if (flags & INPUT) { syntax("One input only"); } filename = *argv; flags |= INPUT; } } if (flags & INPUT) { crasm(flags); } else { syntax("No input!"); } return 0; } void crasm(int flag) { init_label_list(pseudos); file = fopen(filename, "r"); if (file == NULL) { crasm_fatal("can't open source file"); } scode = NULL; llen = 76; plen = 66; ppos = 0 ; lpos = 0; #ifdef DEBUG asmflags = F_NOCODE; #else asmflags = F_NOLIST | F_NOWARNING | F_NOERROR | F_NOCODE; #endif pass(1); #ifdef DEBUG outputEOP(); #endif asmflags &= ~F_NOERROR; if (flag & SCODE) { asmflags &= ~F_NOCODE; } if (flag & LIST) { asmflags &= ~F_NOLIST; } if (flag & WARN) { asmflags &= ~F_NOWARNING; } undeflabels(lroot); pass(2); if (scode) { closescodefile(); } asmflags |= F_LIST_ON; if (errnumber == 0 && flag & LIST) { flag |= XREF; } result(); if (errnumber && (flag & SCODE)) { remove(scodename); } if (flag & XREF) { xref(); } } void pass(int n) { clearerr(file); rewind(file); asmflags |= F_CODE_ON; if (!(asmflags & F_NOLIST)) { asmflags |= F_LIST_ON; } #ifdef DEBUG asmflags |= F_IFLIST_ON | F_MACROLIST_ON; #else asmflags &= ~ F_MACROLIST_ON; asmflags |= F_IFLIST_ON; #endif macrolevel = 0; thiscall = 0; segment = 0; includelevel = 0; linenumber = 0; lineprefix = 0; starlabel = findlabel("*"); starlabel->flags |= UNDEF; starlabel->flags &= ~(NOREDEF | FORWARD); passnumber = n; fprintf(stderr, "Pass #%d\n", n); errnumber = warnnumber = 0; while (!feof(file)) { if (setjmp(errorjump)) { errnumber++; } linegets(curline, 250); if (asmline(curline, 3)) { crasm_error("ELSE, ENDC, ENDM, EXITM illegal here"); } } } static void herelabel(char* label) { if (strcmp(label, "*") == 0) { crasm_error("illegal star definition"); } if (asmflags & F_ORG_GV) { deflabel(label, NOREDEF, asmflags & F_RELATIF ? L_RELATIVE : L_ABSOLUTE, starlabel->value); } else { crasm_error("undefinable label: no org given"); } if (!(asmflags & F_CODE_ON)) { if (macrolevel == 0 || asmflags & F_MACROLIST_ON) { if (lpos == 0) { position(2); outputaddr(starlabel->value); } } } } static struct label* findmnemo(char* mnemo) { char* aux1; char* aux2; register struct label* labmnemo; labmnemo = searchlabel(mnemo); if (labmnemo == NULL) /* sizer 68k */ { if (filter(mnemo, "?.?", &aux1, &aux2)) { if ((labmnemo = searchlabel(aux1))) { if (labmnemo->modifier >= 0) { labmnemo = NULL; } } } } if (labmnemo) { if (!(labmnemo->flags & UNDEF)) { if (labmnemo->type == L_MNEMO || labmnemo->type == L_MACRO) { return labmnemo; } } } return NULL; } static int nospacein(char* s) { while (*s) { if (*s == ' ' || *s == '\t') { return FALSE; } s++; } return TRUE; } int asmline(char* s, int status) { char* label; char* mnemo; char* oper; register struct label* labmnemo; int linestartswithoutblanks = 0; advance = 0; if (starlabel->flags & UNDEF) { asmflags &= ~F_ORG_GV; } else { asmflags |= F_ORG_GV; setpc(starlabel->value); } zerobuffer(); if (*s != ' ' && *s != '\t') { linestartswithoutblanks = 1; } /* on traite XXX ; REMARK puis les cas XXX = blanc */ if (filter(s, "_?_;?", &label, &mnemo)) { s = label; } else { register char* p = s; while (*p) { p++; } while (p > s && (*--p == ' ' || *p == '\t')) { *p = 0; } while (*s == ' ' || *s == '\t') { s++; } } if (*s == 0) { if (status & 1) { outputline(); } return 0; } /* autorise: LABEL = MNEMO MNEMO LABEL MNEMO MNEMO OPERAND LABEL MNEMO OPERAND also: LABEL when line starts without blanks */ if (filter(s, "?_=_?", &label, &oper) && nospacein(label)) { mnemo = "equ"; labmnemo = findmnemo(mnemo); if (checklabel(label) == FALSE) { crasm_error("malformed label"); } } else { oper = NULL; mnemo = NULL; label = NULL; start: if (filter(s, "? _?", &mnemo, &oper) && *mnemo && *oper) { labmnemo = findmnemo(mnemo); if (labmnemo == NULL && label == NULL) { label = mnemo; if (checklabel(label) == FALSE) { crasm_error("malformed label"); } s = oper; goto start; } } else { labmnemo = findmnemo(mnemo = s); oper = NULL; } } if (labmnemo == NULL) { if (linestartswithoutblanks && label == NULL && oper == NULL && mnemo != NULL) { label = mnemo; if (status & 2) { herelabel(label); } if (status & 1) { outputline(); } return 0; } crasm_error("unknown macro or mnemonic"); } if (labmnemo->flags & NOLABEL) { if (label) { crasm_error("labels not allowed here"); } } if (labmnemo->flags & DEFLABEL) { if (!label) { crasm_error("label required here"); } } else if (label) { if (status & 2) { herelabel(label); } } if (labmnemo->flags & DEFCOND) { return (*labmnemo->ptr)(status, label, mnemo, oper); } if (labmnemo->flags & DEFMACRO) { return (*labmnemo->ptr)(status, label, mnemo, oper); } if (labmnemo->type == L_MACRO) { if (label && oper && !strncmp(oper, "MACRO", 5)) { crasm_error("macro is already defined"); } if (status & 2) { macrocall(labmnemo, status, oper); } else if (status & 1) { outputline(); } return 0; } else if (labmnemo->type == L_MNEMO) { if (status & 2) { (*labmnemo->ptr)(labmnemo->modifier, label, mnemo, oper); } starlabel->value += advance; if (status & 1) { outputline(); } return 0; } else { crasm_fatal("proc asmline failure"); } return 0; } /* F_LIST_ON est pris en compte dans outputline() F_CODE_ON est pris en compte dans insertbyte() F_NOLIST est pris en compte dans LIST ON F_NOCODE est pris en compte dans CODE ON ou OFF F_NOERROR dans error F_NOWARNING dans warning */ /* ERRORS ROUTINES */ void crasm_error(char* s) { char raw[80]; int oldflags; char c = toupper(*s); oldflags = asmflags; if (!(asmflags & F_NOERROR)) { sprintf(raw, "%7d ERROR: %c%s", linenumber, c, s + 1); for (s = raw; s[1] == ' '; s++) { s[0] = '>'; } asmflags |= F_LIST_ON; outputraw(raw); } outputline(); if (advance != 0) { starlabel->value += advance; } asmflags = oldflags; longjmp(errorjump, -1); } void crasm_warning(char* s) { char raw[80]; char c = toupper(*s); if (!(asmflags & F_NOWARNING)) { sprintf(raw, "%7d WARNING: %c%s", linenumber, c, s + 1); for (s = raw; s[1] == ' '; s++) { s[0] = '>'; } outputraw(raw); } } void crasm_fatal(char* s) { printf("FATAL ERROR: %s\n", s); exit(10); } void fileerror(char* s) { printf("FILE ERROR on %s file: %s\n", s, strerror(errno)); } /* aff CPU known */ extern struct cpulist { char* name; int code; int (*init)(int); } cpulist[]; void syntax(char* s) { register struct cpulist* q; register int(*a)(int); a = NULL; printf("%s\n", s); printf("Syntax: crasm [-slx] [-o SCODEFILE] INPUTFILE\n"); printf("Crasm %s known CPUs:", CRASMVERSION); for (q = cpulist; q->name ; q++) { if (a != q->init) { printf("\n\t"); } printf(" %s", q->name); a = q->init; } printf("\n"); exit(10); } void setflag(int f) { asmflags |= f; } void clrflag(int f) { asmflags &= ~f; } crasm-1.11/src/dcl.h000066400000000000000000000124201475737230500142570ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* CRASM: dcl.h definition generales LYB 9/87 */ #ifndef DCL_H #define DCL_H #include #include #include #include #include #include #include #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif typedef signed char byte; /***************************************************************************/ extern int asmflags; extern int passnumber; extern int macrolevel; extern int advance; extern FILE* file; extern FILE* scode; extern char* filename; extern char* scodename; extern char curline[256]; extern int linenumber; extern char lineprefix; /* asmflags */ #define F_CPU_GV (1<<0) #define F_ORG_GV (1<<1) #define F_CODE_ON (1<<2) #define F_LIST_ON (1<<3) #define F_IFLIST_ON (1<<4) #define F_MACROLIST_ON (1<<6) #define F_INCLUDELIST_ON (1<<7) #define F_LOHI (1<<8) #define F_ADDR16 (1<<9) #define F_ADDR24 (1<<10) #define F_RELATIF (1<<11) #define F_CODE_HEX (1<<12) #define F_CODE_SCODE (1<<13) #define F_NOLIST (1<<16) #define F_NOWARNING (1<<17) #define F_NOERROR (1<<18) #define F_NOCODE (1<<19) /* plus CPU defined FLAGS */ extern int plen; extern int ppos; extern int llen; extern int lpos; /***************************************************************************/ /* external: crasm.c */ extern void jmp_buf_copy(jmp_buf in, jmp_buf out); extern void crasm(int flag); extern void pass(int pass); extern int asmline(char* s, int status); extern void crasm_error(char* s); extern void crasm_warning(char* s); extern void crasm_fatal(char* s); extern void syntax(char* s); extern void fileerror(char* s); extern void setflag(int f); extern void clrflag(int f); /* external: filter.c */ extern void zerobuffer(void); extern int filter(char* s, char* fil, ...); extern void reverse(char* s); /* external: scode.c */ extern void flushscoderaw(void); extern void closescodefile(void); extern void setpc(long unsigned int addr); extern void insert8(unsigned char x); extern void insert16(short unsigned int x); extern void insert24(unsigned int x); extern void insert32(unsigned int x); /* external: output.c */ extern void settitle(char* s); extern void setpage(int xplen, int xllen); extern void outputraw(char* s); extern void outputEOP(void); extern void output(char* s); extern void outputcar(char c); extern void position(int n); extern void outputEOL(void); extern void outputline(void); extern void outputbyte(int b); extern void outputaddr(unsigned long a); extern char hexa[]; /* external: macros.c */ extern void linegets(char* buffer, int length); extern int Xmacro(int status, char* label, char* mnemo, char* oper); extern int Xexitm(int status, char* label, char* mnemo, char* oper); extern int Xendm(int status, char* label, char* mnemo, char* oper); extern int Xif(int status, char* label, char* mnemo, char* oper); extern int Xelse(int status, char* label, char* mnemo, char* oper); extern int Xendc(int status, char* label, char* mnemo, char* oper); /* external: pseudos.c */ extern int Xequ(int modifier, char* label, char* mnemo, char* oper); extern int Xinclude(int modifier, char* label, char* mnemo, char* oper); extern int Xdc(int modifier, char* label, char* mnemo, char* oper); extern int Xds(int modifier, char* label, char* mnemo, char* oper); extern int Xalign(int modifier, char* label, char* mnemo, char* oper); extern int Xoutput(int modifier, char* label, char* mnemo, char* oper); extern int Xcpu(int modifier, char* label, char* mnemo, char* oper); extern int Xnam(int modifier, char* label, char* mnemo, char* oper); extern int Xasc(int modifier, char* label, char* mnemo, char* oper); extern int Xcode(int modifier, char* label, char* mnemo, char* oper); extern int Xdummy(int modifier, char* label, char* mnemo, char* oper); extern int Xskip(int modifier, char* label, char* mnemo, char* oper); extern int Xpage(int modifier, char* label, char* mnemo, char* oper); extern int Xlist(int modifier, char* label, char* mnemo, char* oper); extern int Xmlist(int modifier, char* label, char* mnemo, char* oper); extern int Xclist(int modifier, char* label, char* mnemo, char* oper); extern int Xilist(int modifier, char* label, char* mnemo, char* oper); extern int Xfail(int modifier, char* label, char* mnemo, char* oper); #endif crasm-1.11/src/filter.c000066400000000000000000000106671475737230500150100ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* CRASM: filter.c comparaison et filtrage LYB 9/87 */ #include "dcl.h" #define WILDCARD '?' /* n'importe quoi. test () '' "" \x */ #define SPACES '_' /* saute X espaces, X>=0 */ char* bufferpos; char buffer[4000]; unsigned int chars_consumed_by_filter; /* zerobuffer() Efface les buffers de tous les filter(s,f) precedents */ void zerobuffer(void) { bufferpos = buffer; } /* filter(s,f, ..&{char*}..) Retourne TRUE si s correspond au filtre f. WILDCARD signifie n'importe quelle chaine, SPACES signifie un nombre quelconque de TABS ou SPACE, un au moins tient compte des '' "" et des () imbriquees. */ int filter(char* s, char* fil, ...) { va_list ap; register char* starts; register char* startf; register int quote; char* oldbufferpos; char* str_start = (s) ? s : ""; s = str_start; oldbufferpos = bufferpos; starts = NULL; startf = NULL; va_start(ap, fil); quote = 0; do { if (*fil == WILDCARD) { char** strptr = va_arg(ap, char**); *bufferpos = 0; *strptr = ++bufferpos; chars_consumed_by_filter = (s - str_start); if (fil[1] == 0) { while (*s) { *bufferpos++ = *s++; } *bufferpos = 0; va_end(ap); return TRUE; } else { startf = fil; starts = s; } } else if (*fil == SPACES) { while (*s == ' ' || *s == '\t') { s++; } } else if (!quote && (toupper(*fil) == toupper(*s) || (*fil == ' ' && *s == '\t'))) { s++; } else { if (startf == NULL || *s == 0) { *bufferpos = 0; bufferpos = oldbufferpos; return FALSE; } if (quote & 0x4) { quote &= ~0x4; /* "\x" ok */ } else { switch (*starts) { case '\\': if (quote & 0x3) /* str only */ { quote |= 0x4; } break; case '\'': if (!(quote & 0x2)) /* 'x"x' ok */ { quote ^= 0x1; } break; case '\"': if (!(quote & 0x1)) /* "x'x" ok */ { quote ^= 0x2; } break; case '(' : if (!(quote & 0x3)) /* "x(x" ok */ { quote += 0x8; /* bonnes () */ } break; case ')' : if (!(quote & 0x3)) /* "x)x" ok */ { quote -= 0x8; } break; } } *bufferpos++ = *starts; s = ++starts; fil = startf; } } while (*fil++ != 0); *bufferpos = 0; va_end(ap); return TRUE; } void reverse(char* s) { register char* d; register char* f; register char c; register int quote = 0; d = s; f = s; while (*d) { d++; } while (--d > f) { c = *f; *f++ = *d; *d = c; } for (d = s; *d; d++) { switch (*d) { case '\'': if (! quote) { quote |= 0x1; } else if (quote & 0x1) { if (d[1] != '\\') { quote &= ~0x1; } } break; case '\"': if (! quote) { quote |= 0x2; } else if (quote & 0x2) { if (d[1] != '\\') { quote &= ~0x2; } } break; case '\\': if (quote) { d[0] = d[-1]; d[-1] = '\\'; } break; } } } crasm-1.11/src/label.c000066400000000000000000000136661475737230500146040ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* CRASM: label.c utilisation des labels LYB 9/87 */ #include "dcl.h" #include #include "label.h" #define LABELARRAYSIZE 100 struct labelarray { int position; struct label label[LABELARRAYSIZE]; }* labelarray_inst = NULL; struct label* lroot = NULL; /* checklabel(name) Retourne TRUE si name est une chaine acceptable pour un label */ int checklabel(char* name) { register char c; if (strlen(name) > LABLEN) { return FALSE; } c = *name; if (c == '*' && name[1] == 0) { return TRUE; } if (!isalpha(c) && c != '_' && c != '.') { return FALSE; } while ((c = *++name) != 0) { if (!isalnum(c) && c != '_' && c != '.') { return FALSE; } } return TRUE; } /* searchlabel(name) Retourne NULL ou l'adresse du label 'name' stocke dans addrpos l'adresse du pointeur vers ce label */ static struct label** addrpos; static char localname[LABLEN + 2]; struct label* searchlabel(char* name) { register struct label* q; register int r; register char* s; extern int segment; s = localname; if (name[0] == '.') { sprintf(s, "%d", segment); while (*s) { s++; } } while (s - localname < LABLEN) { if (*name) { *s++ = toupper(*name++); } else { *s++ = 0; } } s = localname; q = lroot; addrpos = &lroot; while (q != NULL && (r = strncmp(s, q->name, LABLEN)) != 0) { if (r > 0) { q = * (addrpos = &(q->right)) ; } else { q = * (addrpos = &(q->left)) ; } } return q; } /* makelabel(name,flags,type) Cree et place le label ci dessus. */ struct label* makelabel(char* name, unsigned char flags, unsigned char type) { register struct label* q; q = searchlabel(name); if (q != NULL) { crasm_fatal("XX: makelabel"); } if (labelarray_inst == NULL) { if ((labelarray_inst = malloc(sizeof * labelarray_inst))) { memset(labelarray_inst, 0, sizeof(*labelarray_inst)); } else { crasm_fatal("no memory"); } } q = &(labelarray_inst->label[ labelarray_inst->position++ ]); if (labelarray_inst->position >= LABELARRAYSIZE) { labelarray_inst = NULL; } q->left = NULL; q->right = NULL; *addrpos = q; strncpy(q->name, localname, LABLEN); q->type = type; q->flags = flags; return q; } /* findlabel(name) Renvoie un pointeur sur le label 'name'. Si necessaire, cree un label UNDEF|FORWARD type L_ADDR: seule reference en avant autorisee. */ struct label* findlabel(char* name) { register struct label* q; q = searchlabel(name); if (q == NULL) { q = makelabel(name, UNDEF | FORWARD | NOREDEF, asmflags & F_RELATIF ? L_RELATIVE : L_ABSOLUTE); } q->flags |= USED; return q; } /* deflabel(name,flags,type,value) Definit un label name, de type precise, pour une valeur val1. Si ce label existe deja, il doit etre redefini du meme type, et si ce type est L_ADDR, il doit etre indefini. */ struct label* deflabel(char* name, unsigned char flags, unsigned char type, long value) { register struct label* q; q = searchlabel(name); if (q == NULL) { q = makelabel(name, UNDEF, type); } if (!(q->flags & UNDEF)) { if ((q->flags & NOREDEF) || (flags & NOREDEF)) { if (q->type == L_ABSOLUTE || q->type == L_RELATIVE) { crasm_error("illegal label redefinition"); } else { crasm_error("attempt to redefine a keyword"); } } } q->flags &= USED | NOREDEF | FORWARD; flags &= ~USED; q->type = type; q->flags |= flags; q->ptr = NULL; q->value = value; return q; } /* init_label_list Ordonne en arbre un tableau de labels */ void init_label_list(struct label* array) { register int i; register int count; register int incr; register struct label* q; q = array; count = 0; while (q++->left != (void*) -1) { count++; } incr = 1; array--; while (incr <= count) { incr <<= 1; } while (incr > 1) { i = incr >> 1; while (i <= count) { q = array + i; if (searchlabel(q->name) != NULL) { if (q->flags & UNDEF) { q->flags &= ~UNDEF; } else { crasm_warning("user's symbol overrides new keyword"); } } else { *addrpos = q; strncpy(q->name, localname, LABLEN); } i += incr; } incr >>= 1; } } /* undeflabels(lroot) UNDEF tous les labels de type positif, sauf les FORWARD */ void undeflabels(struct label* q) { extern struct label pseudos[]; if (q) { if (!(q->flags & NOREDEF) || (q->flags & UNDEF)) { q->flags &= ~FORWARD; } /* FORWARD ne subsiste que si on a - un label non redefinissable, - ce label est effectivement defini en avant quelque-part */ q->flags |= UNDEF; undeflabels(q->left); undeflabels(q->right); } for (q = pseudos; q->left != (struct label*) - 1; q++) { q->flags &= ~UNDEF; } } crasm-1.11/src/label.h000066400000000000000000000052501475737230500145770ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* crasm: label.h definition des labels LYB 9/87 */ #ifndef LABEL_H #define LABEL_H #define LABLEN 48 struct label { struct label* left; struct label* right; char name[LABLEN]; byte flags; byte type; int modifier; int (*ptr)(int, char*, char*, char*); long value; }; struct result { byte flags; byte type; int modifier; int (*ptr)(int, char*, char*, char*); long value; }; /* type */ #define L_MNEMO -1 #define L_MACRO 2 #define L_ABSOLUTE 3 #define L_RELATIVE 4 #define L_REGS 5 #define L_DIRECTBIT 6 /* etc... */ /* flags modifier < 0 => size field allowed 68k-like */ #define UNDEF (1<<0) #define FORWARD (1<<1) #define USED (1<<2) #define NOREDEF (1<<3) #define NOLABEL (1<<4) /* pour mnemos uniquement */ #define DEFLABEL (1<<5) #define DEFMACRO (1<<6) #define DEFCOND (1<<7) /* external: label.c */ extern int checklabel(char* name); extern struct label* searchlabel(char* name); extern struct label* findlabel(char* name); extern struct result* parse(char* expr); extern struct label* makelabel(char* name, unsigned char flags, unsigned char type); extern struct label* deflabel(char* name, unsigned char flags, unsigned char type, long value); extern void init_label_list(struct label* array); extern void undeflabels(struct label* q); /* external: xref.c */ extern void printlabel(struct label* label); extern void result(void); extern void xref(void); /* external: parse.c */ extern struct result* parse(char* expr); /* external: macros.c */ extern int macrocall(struct label* labmacro, int status, char* oper); /* external: pseudos.c */ extern void checktype(struct result* r, int type); /* common */ extern struct label* lroot; extern struct label* starlabel; #endif crasm-1.11/src/macro.c000066400000000000000000000335141475737230500146200ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* CRASM: macro.c gestion des macros et des pseudos conditionnelles LYB 9/87 */ #include "dcl.h" #include "label.h" #include #include #define MAXSOURCEDEEP 10 extern jmp_buf errorjump; extern int errnumber; /* code des instructions */ /* if, macro retournent 0 */ #define ENDC 0x11 #define ELSE 0x12 #define ENDM 0x21 #define EXITM 0x22 /* if, else, endc */ int Xelse(int status, char* label, char* mnemo, char* oper) { if (oper) { crasm_error("no operand allowed for ELSE"); } return ELSE; } int Xendc(int status, char* label, char* mnemo, char* oper) { if (oper) { crasm_error("no operand allowed for ENDC"); } return ENDC; } #define EQ 1 #define GT 2 #define LT 4 #define NE 8 static struct compar { char* comp; int flag; } compar[] = { { "?_>=_?", GT | EQ, }, { "?_<=_?", LT | EQ, }, { "?_==_?", EQ, }, /* habitues du C */ { "?_!=_?", NE, }, { "?_=_?", EQ, }, { "?_<>_?", NE, }, { "?_<_?", LT, }, { "?_>_?", GT, }, { NULL, NE } }; static struct result zero = { 0, L_ABSOLUTE, 0, 0, 0 }; static int testtrue(char* oper) { char* s1, *s2; register struct compar* q; struct result r1, r2; if (!oper || !*oper) { return FALSE; } q = compar; while (q->comp) { if (filter(oper, q->comp, &s1, &s2)) { break; } q++; } if (!q->comp) { r1 = *parse(oper); r2 = zero; } else { r1 = *parse(s1); r2 = *parse(s2); } if (((r1.flags & UNDEF) && (r1.flags & FORWARD)) || ((r2.flags & UNDEF) && (r2.flags & FORWARD))) { crasm_error("forward defined expressions are illegal here"); } if (r1.type != r2.type) { crasm_error("Uncomparable expressions"); } if (q->flag & (GT | LT)) { if ((r1.type != L_ABSOLUTE) && (r1.type != L_RELATIVE)) { crasm_error("not a numeric expression"); } if ((q->flag & GT) && (r1.value > r2.value)) { return TRUE; } if ((q->flag & LT) && (r1.value < r2.value)) { return TRUE; } } if (q->flag & EQ) { if (r1.modifier == r2.modifier && r1.value == r2.value) { return TRUE; } } if (q->flag & NE) { if (r1.modifier != r2.modifier || r1.value != r2.value) { return TRUE; } } return FALSE; } int Xif(int status, char* label, char* mnemo, char* oper) { int flag; int mystatus; int booleanvalue; char oldprefix; jmp_buf errjmpsav; booleanvalue = FALSE; if (status & 2) { booleanvalue = testtrue(oper); } mystatus = 0; if (booleanvalue) { mystatus |= 3; } if (asmflags & F_IFLIST_ON) { mystatus |= 1; } if (asmflags & F_IFLIST_ON) { if (status & 1) { outputline(); } } oldprefix = lineprefix; if (status & 2) { if (!(mystatus & 2)) { lineprefix = 'C'; } } jmp_buf_copy(errjmpsav, errorjump); do { if (setjmp(errorjump)) { errnumber++; } linegets(curline, 250); if (feof(file)) { jmp_buf_copy(errorjump, errjmpsav); crasm_error("Unexpected End of File"); } flag = asmline(curline, status & mystatus); if (!(status & mystatus & 2)) { if (flag == EXITM) { flag = 0; } } } while (flag == 0); jmp_buf_copy(errorjump, errjmpsav); lineprefix = oldprefix; if (flag == ENDM) { crasm_error("ENDM illegal here"); } if (asmflags & F_IFLIST_ON) { if (status & 1) { outputline(); } } if (flag == ENDC) { return 0; } if (flag == EXITM) { return EXITM; } mystatus = 0; if (!booleanvalue) { mystatus |= 3; } if (asmflags & F_IFLIST_ON) { mystatus |= 1; } if (status & 2) { if (!(mystatus & 2)) { lineprefix = 'C'; } } do { if (setjmp(errorjump)) { errnumber++; } linegets(curline, 250); if (feof(file)) { jmp_buf_copy(errorjump, errjmpsav); crasm_error("Unexpected End of File"); } flag = asmline(curline, status & mystatus); if (!(status & mystatus & 2)) { if (flag == EXITM) { flag = 0; } } } while (flag == 0); jmp_buf_copy(errorjump, errjmpsav); lineprefix = oldprefix; if (flag == ENDM || flag == ELSE) { crasm_error("ELSE or ENDM illegal here"); } if (asmflags & F_IFLIST_ON) { if (status & 1) { outputline(); } } if (flag == ENDC) { return 0; } if (flag == EXITM) { return EXITM; } return 0; } /* MACRO, ENDM, EXITM */ /* On aborde la gestion des Macros */ struct macroline { struct macroline* next; char line[1 /* variable */ ]; }; int Xexitm(int status, char* label, char* mnemo, char* oper) { if (oper) { crasm_error("no operand allowed in EXITM statement"); } if (!macrolevel && (status & 1)) { outputline(); } if (macrolevel && (status & 2)) { return EXITM; } return 0; } int Xendm(int status, char* label, char* mnemo, char* oper) { if (oper) { crasm_error("no operand allowed in ENDM statement"); } if (!macrolevel && (status & 1)) { outputline(); } if (macrolevel && (status & 2)) { return ENDM; } return 0; } int Xmacro(int status, char* label, char* mnemo, char* oper) { jmp_buf errjmpsav; char* s1; char* s2; struct macroline* startmacro; register struct macroline** where; char mname[LABLEN + 1]; struct label* lbl = 0; where = &startmacro; strncpy(mname, label, LABLEN); mname[LABLEN] = 0; if (oper) { crasm_error("no operand allowed in macro statement"); } if (macrolevel) { crasm_error("nested macro definition"); } if (status & 1) { outputline(); } if (status & 2) { lbl = deflabel(mname, 0, L_MACRO, 0); lbl->ptr = 0; } jmp_buf_copy(errjmpsav, errorjump); do { if (setjmp(errorjump)) { errnumber++; } zerobuffer(); linegets(curline, 250); if (feof(file)) { jmp_buf_copy(errorjump, errjmpsav); crasm_error("Unexpected End of File"); } if (!filter(curline, "?_;?", &s1, &s2)) { s1 = curline; } if (status & 2) { *where = (struct macroline*) malloc(sizeof(struct macroline) + strlen(s1)); (*where)->next = NULL; strcpy((*where)->line, s1); where = & ((*where)->next); } if (status & 1) { outputline(); } } while (! filter(s1, "_?_ENDM_?", &s1, &s2)); jmp_buf_copy(errorjump, errjmpsav); if (*s1 || *s2) { crasm_error("illegal ENDM instruction"); } if (lbl) { lbl->ptr = (void*)startmacro; } return 0; } /* linegets(buffer,length) access principal */ union { byte type; struct { byte type; byte oldlist; byte oldprefix; int oldlinnum; FILE* file; } filedesc; struct { byte type; byte oldlist; byte oldprefix; int oldlinnum; char (*replace)[60]; int numarg; struct macroline* mlineptr; } macrodesc; } source[MAXSOURCEDEEP]; int sourcelevel = -1; int includelevel; #define S_END 0 #define S_FILE 1 #define S_MACRO 2 void linegets(char* buffer, int length) { register int slevel; slevel = sourcelevel; if (slevel < 0) { slevel = sourcelevel = 0; source[slevel].type = S_FILE; source[slevel].filedesc.file = file; } while (source[slevel].type == S_END) { if (slevel == 0) { source[slevel].type = S_FILE; break; } linenumber = source[slevel].filedesc.oldlinnum; lineprefix = source[slevel].filedesc.oldprefix; asmflags &= ~ F_LIST_ON; if (source[slevel].filedesc.oldlist) { asmflags |= F_LIST_ON; } includelevel--; fclose(source[slevel].filedesc.file); sourcelevel = --slevel; } if (source[slevel].type == S_FILE) { register char* s1; register char* s2; buffer[0] = 0; s1 = fgets(buffer, length, source[slevel].filedesc.file); s2 = buffer; s1 = buffer; while (s1 && *s1 && *s1 != '\n' && s1 - buffer < length) { if (*s1 == '\t' || isprint((unsigned char)*s1) || (((unsigned char)*s1 & 0x80) != 0)) { *s2++ = *s1; } s1++; } *s2 = 0; if (s1 != s2) { crasm_warning("Unprintable characters removed"); } linenumber++; if ((linenumber & 7) == 1 && passnumber == 1) { fprintf(stderr, "%d \r", linenumber); fflush(stderr); } if (feof(source[slevel].filedesc.file)) { source[slevel].type = S_END; } } else { register struct macroline* q; int numarg; char (*replace)[60]; register char* s1; register char* s2; q = source[slevel].macrodesc.mlineptr; numarg = source[slevel].macrodesc.numarg; replace = source[slevel].macrodesc.replace; s1 = buffer; s2 = q->line; if (!q) { crasm_fatal("internal macrocall error"); } source[slevel].macrodesc.mlineptr = q->next; while (*s2) { if (s1 - buffer > length - 10) { crasm_warning("Too long line"); break; } if (*s2 != '\\') { *s1++ = *s2++; continue; } s2++; if (*s2 == '#') { s2++; *s1++ = numarg + '0'; } else if (*s2 == '*' || (*s2 >= '1' && *s2 <= '9')) { char* s = 0; if (*s2 == '*') { s = replace[9]; } else if (*s2 >= '0' && *s2 <= numarg + '0') { s = replace[ *s2 - '1' ]; } while (s && *s) { if (s1 - buffer > length - 10) { break; } *s1++ = *s++; } s2++; } else { *s1++ = '\\'; } } *s1 = 0; } } /* include */ int Xinclude(int modifier, char* label, char* mnemo, char* oper) { FILE* f; register int slevel; if (!oper) { crasm_error("no filename"); } f = fopen(oper, "r"); if (f == NULL) { crasm_error("can't open include file"); } slevel = sourcelevel + 1; if (slevel >= MAXSOURCEDEEP) { crasm_fatal("too many nested INCLUDEs and MACROs"); } source[slevel].type = S_FILE; source[slevel].filedesc.oldlinnum = linenumber; source[slevel].filedesc.oldprefix = lineprefix; source[slevel].filedesc.oldlist = (asmflags & F_LIST_ON) ? 1 : 0; source[slevel].filedesc.file = f; if (asmflags & F_LIST_ON) { outputline(); } linenumber = 0; sourcelevel = slevel; includelevel++; if (!(asmflags & F_INCLUDELIST_ON)) { asmflags &= ~F_LIST_ON; } return 0; } /* macrocall */ int thiscall; extern int segment; int macrocall(struct label* labmacro, int status, char* oper) { char replace[10][60]; register int slevel; register int flag; int numarg; int oldsegment; int mystatus; jmp_buf errjmpsav; char curlinesav[256]; labmacro->flags |= USED; strcpy(curlinesav, curline); slevel = sourcelevel + 1; if (slevel >= MAXSOURCEDEEP) { crasm_fatal("too many nested INCLUDEs and MACROs"); } source[slevel].type = S_MACRO; source[slevel].macrodesc.oldlinnum = linenumber; source[slevel].macrodesc.oldprefix = lineprefix; source[slevel].macrodesc.oldlist = (asmflags & F_LIST_ON) ? 1 : 0; numarg = 0; oldsegment = segment; replace[9][0] = 0; if (oper && *oper) { strncpy(replace[9], oper, 59); replace[9][59] = 0; } while (oper && *oper) { char* arg1; char* arg2; if (numarg > 8) { crasm_error("Too many arguments in a macro call"); } if (filter(oper, "?_,_?", &arg1, &arg2)) { oper = arg2; strncpy(replace[numarg], arg1, 59); replace[numarg++][59] = 0; } else { strncpy(replace[numarg], oper, 59); replace[numarg++][59] = 0; oper = NULL; } } source[slevel].macrodesc.mlineptr = (struct macroline*) labmacro->ptr; source[slevel].macrodesc.numarg = numarg; source[slevel].macrodesc.replace = replace; if (asmflags & F_MACROLIST_ON) { if (status & 1) { outputline(); } } lineprefix = 'M'; sourcelevel = slevel; macrolevel++; segment = ++thiscall; mystatus = 2; if ((asmflags & F_MACROLIST_ON)) { mystatus |= 1; } jmp_buf_copy(errjmpsav, errorjump); do { if (setjmp(errorjump)) { errnumber++; } linegets(curline, 250); flag = asmline(curline, status & mystatus); } while (flag == 0); macrolevel--; linenumber = source[slevel].filedesc.oldlinnum; lineprefix = source[slevel].filedesc.oldprefix; asmflags &= ~ F_LIST_ON; if (source[slevel].filedesc.oldlist) { asmflags |= F_LIST_ON; } sourcelevel = --slevel; segment = oldsegment; jmp_buf_copy(errorjump, errjmpsav); if (flag != ENDM && flag != EXITM) { crasm_error("ELSE or ENDC illegal here"); } if (!(asmflags & F_MACROLIST_ON)) { strcpy(curline, curlinesav); if (status & 1) { outputline(); } } return 0; } crasm-1.11/src/operator.c000066400000000000000000000214171475737230500153510ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* CRASM: operator.c evaluation d'expressions LYB 9/87 */ #include "dcl.h" #include #include "label.h" /**************************************** Usage general */ static void cst(struct result* presult, long int val) { presult->flags = 0; presult->type = L_ABSOLUTE; presult->value = val; } static char overflow[] = "overflow"; static char badtype[] = "illegal operator"; /**************************************** Constantes */ void cstdecimal(struct result* presult, struct result* parg, char* s) { register unsigned long val; register int r; val = 0; while (*s) { if (!isdigit(*s)) { crasm_error("bad decimal number"); } r = *s - '0'; if (val > 0xffffffff / 10) { crasm_error(overflow); } val *= 10; if (val > 0xffffffff - r) { crasm_error(overflow); } val += r; s++; } cst(presult, val); } void csthexa(struct result* presult, struct result* parg, char* s) { register unsigned long val; register int r; val = 0; while (*s) { if (!isxdigit(*s)) { crasm_error("bad hexadecimal number"); } if (*s >= 'a') { r = *s - 'a' + 10; } else if (*s >= 'A') { r = *s - 'A' + 10; } else { r = *s - '0'; } if (val > 0xfffffff) { crasm_error(overflow); } val = (val << 4) + r; s++; }; cst(presult, val); } void cstoctal(struct result* presult, struct result* parg, char* s) { register unsigned long val; register int r; val = 0; while (*s) { if (*s < '0' || *s > '7') { crasm_error("bad octal number"); } r = *s - '0'; if (val > 0x1fffffff) { crasm_error(overflow); } val = (val << 3) + r; s++; } cst(presult, val); } void cstbinary(struct result* presult, struct result* parg, char* s) { register unsigned long val; register int r; val = 0; while (*s) { if (*s != '1' && *s != '0') { crasm_error("bad binary number"); } r = *s - '0'; if (val > 0xefffffff) { crasm_error(overflow); } val = (val << 1) + r; s++; } cst(presult, val); } void cstascii(struct result* presult, struct result* parg, char* s) { register unsigned long oval; register unsigned long val; register int r; register char delimit; val = 0; delimit = *s; while (*++s != delimit) { if (!isprint(*s)) { crasm_error("bad ascii constant"); } r = *s; if (r == '\\') { switch (*++s) { case 't': r = '\t'; break; case 'n': r = '\n'; break; case 'r': r = '\r'; break; case '0': r = '\0'; break; case '\"': case '\\': case '\'': r = *s; break; default: crasm_error("Bad \\X sequence"); } } oval = val; val = (val << 8) + r; if ((val >> 8) != oval) { crasm_error(overflow); } } if (*++s) { crasm_error("syntax error"); } cst(presult, val); } void cstlabel(struct result* presult, struct result* parg, char* s) { register struct label* q; q = findlabel(s); presult->flags = q->flags; presult->type = q->type; presult->value = q->value; presult->modifier = q->modifier; presult->ptr = q->ptr; if ((q->flags & UNDEF) && !(q->flags & FORWARD)) { crasm_error("Undefined label"); } } /**************************************** Ops monadiques */ void opminus(struct result* presult, struct result* parg, char* s) { checktype(presult, L_ABSOLUTE); presult->value = -presult->value; } void opnot(struct result* presult, struct result* parg, char* s) { checktype(presult, L_ABSOLUTE); presult->value = ~presult->value; } /**************************************** Ops diadiques */ void opadd(struct result* presult, struct result* parg, char* s) { presult->value += parg->value; presult->flags |= parg->flags; if (presult->type == L_ABSOLUTE && parg->type == L_ABSOLUTE) { presult->type = L_ABSOLUTE; } else if ((presult->type == L_ABSOLUTE && parg->type == L_RELATIVE) || (presult->type == L_ABSOLUTE && parg->type == L_RELATIVE)) { presult->type = L_RELATIVE; } else { crasm_error(badtype); } } void opsub(struct result* presult, struct result* parg, char* s) { presult->flags |= parg->flags; if ((presult->type == parg->type) && (presult->type == L_RELATIVE || presult->type == L_ABSOLUTE)) { presult->type = L_ABSOLUTE; } else if (presult->type == L_RELATIVE && parg->type == L_ABSOLUTE) { presult->type = L_RELATIVE; } else if (presult->type == L_REGS && parg->type == L_REGS) { register int lo = 0; register int hi = 0; while (1 << lo != presult->value && lo < 32) { lo++; } while (1 << hi != parg->value && hi < 32) { hi++; } if (hi > 31 || hi < lo) { crasm_error("illegal register list"); } while (lo <= hi) { presult->value |= 1 << lo; } } else { crasm_error(badtype); } if (presult->type != L_REGS) { presult->value -= parg->value; } } void opbit(struct result* presult, struct result* parg, char* s) { checktype(presult, L_ABSOLUTE); checktype(parg, L_ABSOLUTE); presult->flags |= parg->flags; presult->type = L_DIRECTBIT; presult->modifier = parg->value; if (parg->value > 32) { crasm_error(overflow); } } void opbitaddr(struct result* presult, struct result* parg, char* s) { checktype(presult, L_DIRECTBIT); presult->type = L_ABSOLUTE; presult->modifier = 0; } void opbitnumb(struct result* presult, struct result* parg, char* s) { checktype(presult, L_DIRECTBIT); presult->type = L_ABSOLUTE; presult->value = presult->modifier; presult->modifier = 0; } void oplo(struct result* presult, struct result* parg, char* s) { checktype(presult, L_ABSOLUTE); presult->value &= 0xff; } void ophi(struct result* presult, struct result* parg, char* s) { checktype(presult, L_ABSOLUTE); presult->value >>= 8; presult->value &= 0xff; } void opmul(struct result* presult, struct result* parg, char* s) { checktype(presult, L_ABSOLUTE); checktype(parg, L_ABSOLUTE); presult->flags |= parg->flags; presult->value *= parg->value; } void opdiv(struct result* presult, struct result* parg, char* s) { presult->flags |= parg->flags; checktype(presult, L_ABSOLUTE); checktype(parg, L_ABSOLUTE); if (parg->value != 0) { presult->value /= parg->value; } } void oprlist(struct result* presult, struct result* parg, char* s) { presult->flags |= parg->flags; checktype(presult, L_REGS); checktype(parg, L_REGS); presult->value |= parg->value; } void opor(struct result* presult, struct result* parg, char* s) { checktype(presult, L_ABSOLUTE); checktype(parg, L_ABSOLUTE); presult->flags |= parg->flags; presult->value |= parg->value; } void opand(struct result* presult, struct result* parg, char* s) { checktype(presult, L_ABSOLUTE); checktype(parg, L_ABSOLUTE); presult->flags |= parg->flags; presult->value &= parg->value; } void opxor(struct result* presult, struct result* parg, char* s) { checktype(presult, L_ABSOLUTE); checktype(parg, L_ABSOLUTE); presult->flags |= parg->flags; presult->value ^= parg->value; } void oplsh(struct result* presult, struct result* parg, char* s) { checktype(presult, L_ABSOLUTE); checktype(parg, L_ABSOLUTE); presult->flags |= parg->flags; presult->value <<= parg->value; } void oprsh(struct result* presult, struct result* parg, char* s) { checktype(presult, L_ABSOLUTE); checktype(parg, L_ABSOLUTE); presult->flags |= parg->flags; presult->value >>= parg->value; } void operror(struct result* presult, struct result* parg, char* s) { crasm_error(s); } crasm-1.11/src/output.c000066400000000000000000000130671475737230500150600ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* CRASM: output.c sorties des listings LYB 9/87 */ #include "dcl.h" #include "version.h" #include #define NMARGIN 21 #define LMARGIN 28 /* output(s) position(n); outputEOL() outputEOP() outputline() outputraw(s) settitle(s) */ static int lastoffset; extern unsigned int chars_consumed_by_filter; char linebuffer[1000]; char title[31] = ""; int pagenumber = 0; void settitle(char* s) { static byte flag = 0; if (flag) { crasm_warning("title redefinition"); } if (strlen(s) > 30) { crasm_error("too long title"); } strcpy(title, s); if (passnumber == 2) { flag = 1; } } void setpage(int xplen, int xllen) { static byte flag = 0; if (flag) { crasm_warning("page redefinition"); } if (xplen > 200 || (xplen && xplen < 10) || xllen < 39 || xllen > (int)sizeof(linebuffer)) { crasm_error("illegal values"); } plen = xplen; llen = xllen; if (passnumber == 2) { flag = 1; } } void outputraw(char* s) { register int i; if (asmflags & F_LIST_ON) { if (ppos == 0) { printf("Crasm %s: %30s", CRASMVERSION, title); for (i = 58; i < llen; i++) { putchar(' '); } printf("page%3d\n\n", ++pagenumber); ppos = 2; } puts(s); ppos++; if (ppos >= plen - 2 && plen) { printf("\n\n"); ppos = 0; } } if (ferror(stdout)) { fileerror("output"); } } void outputEOP(void) { if (asmflags & F_LIST_ON) { if (plen) { while (ppos) { outputEOL(); } } else { printf("\n\n\n"); } } } static char* outpat[] = { "_? _? _?", "_? _?", "_?", NULL }; void output(char* s) { while (*s) { outputcar(*s++); } } void outputcar(char c) { char* dummy; char** pat; if (!isspace((unsigned char)c)) { if (lpos >= llen) { outputEOL(); if (filter(linebuffer + LMARGIN, "?;_?", &dummy, &dummy)) /* suite de commentaire */ { position(chars_consumed_by_filter); } else if (c == ';') /* debut de commentaire */ { position(LMARGIN); } else if (lastoffset >= LMARGIN) { position(lastoffset); } else if (c != ';') /* suite d'un champ quelconque */ for (pat = outpat; *pat; pat++) { if (filter(linebuffer + LMARGIN, *pat, &dummy, &dummy, &dummy)) { position(chars_consumed_by_filter); break; } } lastoffset = lpos; } if (isprint((unsigned char)c) || (((unsigned char)c & 0x80) != 0)) { linebuffer[lpos++] = c; } linebuffer[lpos] = 0; } else if (c == ' ') { if (lpos < llen) { linebuffer[lpos++] = ' '; linebuffer[lpos] = 0; } else { lpos++; } } else if (c == '\t') { do { outputcar(' '); } while ((lpos - LMARGIN) % 8); } } void position(int n) { if (n >= llen) { crasm_fatal("line length must be greater"); } while (lpos < n) { outputcar(' '); } } void outputEOL(void) { outputraw(linebuffer); lpos = 0; *linebuffer = 0; } /* peut etre ameliore pour tabuler automatiquement */ void outputline(void) { char linnum[10]; register int i; lastoffset = 0; if (linenumber == 0) { return; /* special pour les include.. */ } if (lineprefix) { sprintf(linnum, " "); i = 5 - macrolevel; if (i < 0) { i = 0; } if (i > 4) { i = 4; } linnum[i] = lineprefix; } else { sprintf(linnum, "%5d", linenumber); } position(NMARGIN); output(linnum); position(LMARGIN); output(curline); outputEOL(); } /* special output */ char hexa[] = "0123456789ABCDEF"; extern unsigned long pc; void outputbyte(int b) { char buffer[3]; static unsigned long mypc; if (advance > 20 && lpos > NMARGIN - 5) { if (lpos <= NMARGIN - 3) { output("..."); } return; } if (lpos > NMARGIN - 3) { outputEOL(); } if (pc != mypc && lpos != 0) { outputEOL(); } if (lpos == 0) { outputaddr(pc); } buffer[0] = hexa[(b >> 4) & 0xF]; buffer[1] = hexa[b & 0xF]; buffer[2] = 0; output(buffer); mypc = pc + 1; } void outputaddr(unsigned long a) { char buffer[20]; register int i; register char* s; s = buffer; i = 28; if (asmflags & F_ADDR24) { i = 20; } else if (asmflags & F_ADDR16) { i = 12; } for (; i >= 0; i -= 4) { *s++ = hexa [(a >> i) & 0xF ]; } *s++ = ' '; *s = 0 ; output(buffer); } crasm-1.11/src/parse.c000066400000000000000000000153441475737230500146320ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* CRASM: parse.c evaluation d'expressions LYB 9/87 */ #include "dcl.h" #include #include "label.h" /* La suite prouve que les methodes classiques ont du bon, et que j'ai eu tort de n'en pas vouloir. REVERSE est une horreur imposee par le sens d'unification de FILTER */ struct result calcresult; extern void opadd(struct result* presult, struct result* parg, char* s); extern void opsub(struct result* presult, struct result* parg, char* s); extern void opmul(struct result* presult, struct result* parg, char* s); extern void opdiv(struct result* presult, struct result* parg, char* s); extern void oprlist(struct result* presult, struct result* parg, char* s); extern void opminus(struct result* presult, struct result* parg, char* s); extern void opor(struct result* presult, struct result* parg, char* s); extern void opand(struct result* presult, struct result* parg, char* s); extern void opxor(struct result* presult, struct result* parg, char* s); extern void oplsh(struct result* presult, struct result* parg, char* s); extern void oprsh(struct result* presult, struct result* parg, char* s); extern void opnot(struct result* presult, struct result* parg, char* s); extern void opbit(struct result* presult, struct result* parg, char* s); extern void csthexa(struct result* presult, struct result* parg, char* s); extern void cstdecimal(struct result* presult, struct result* parg, char* s); extern void cstbinary(struct result* presult, struct result* parg, char* s); extern void cstascii(struct result* presult, struct result* parg, char* s); extern void cstlabel(struct result* presult, struct result* parg, char* s); extern void cstoctal(struct result* presult, struct result* parg, char* s); extern void opbitnumb(struct result* presult, struct result* parg, char* s); extern void opbitaddr(struct result* presult, struct result* parg, char* s); extern void oplo(struct result* presult, struct result* parg, char* s); extern void ophi(struct result* presult, struct result* parg, char* s); extern void operror(struct result* presult, struct result* parg, char* s); struct oplist { char* filtre; short type; short nxt; void (*callop)(struct result*, struct result*, char*); /* (*callop)(&result,&arg,&character) */ } oplist[] = { /* ICI a l'envers , filtres des operations */ { "?_\\_?", 2, 1 /* rlist */, oprlist,}, { "?_+_?", 2, 2 /* add */, opadd,}, { "?_-_?", 2, 1 /* subtract, rrange */, opsub,}, { "?_*_?", 2, 2 /* multiply */, opmul,}, { "?_/_?", 2, 1 /* divide */, opdiv,}, { "?_|_?", 2, 3 /* logical OR */, opor,}, { "?_&_?", 2, 2 /* logical AND */, opand,}, { "?_^_?", 2, 1 /* logical XOR */, opxor,}, { "?_<<_?", 2, 2 /* lshift */, oplsh,}, { "?_>>_?", 2, 1 /* rshift */, oprsh,}, { "?_-", 1, 1 /* unary minus */, opminus,}, { "?_~", 1, 1 /* logical NOT */, opnot,}, { ")_?_(_TIB", 1, 1 /* bit number */, opbitnumb,}, { ")_?_(_RDDA", 1, 1 /* bit addr */, opbitaddr,}, { ")_?_(_OL", 1, 1 /* bit number */, oplo,}, { ")_?_(_IH", 1, 1 /* bit addr */, ophi,}, { "}_?_{_?", 2, 1 /* directbit */, opbit,}, { ")_?_(", -1, 1 /* parenthesis */, operror,}, /* ICI on teste les labels */ { "", -3, 1 /* label */, cstlabel,}, /* ICI a l'endroit constantes autres que ascii ou decimal */ { "$?", -2, 1 /* hexadecimal */, csthexa,}, { "?H", -2, 1 /* Intel hexa */, csthexa,}, { "0X?", -2, 1 /* C hexa */, csthexa,}, { "%?", -2, 1 /* binaire */, cstbinary,}, { "?B", -2, 1 /* Intel binaire*/, cstbinary,}, { "0B?", -2, 1 /* C binaire */, cstbinary,}, { "?Q", -2, 1 /* Intel octal */, cstoctal,}, { NULL, 0, 0, NULL } }; static void parse2(char* expr, struct result* presult) { register char* c1 = 0; register char* c2 = 0; char* ca; char* cb; register int i; register int j; struct result arg; struct oplist* q; q = oplist; while (q->type) { j = -1; switch (q->type) { case 2: /* diadiques */ for (i = 0; i < q->nxt; i++) { ca = cb = NULL; if (filter(expr, q[i].filtre, &ca, &cb)) { if (cb < c2 || j < 0) { c1 = ca; c2 = cb; j = i; } } } if (j < 0 || c1 == NULL || c2 == NULL || !*c1 || !*c2) { break; } parse2(c2, presult); parse2(c1, &arg); (q[j].callop)(presult, &arg, NULL); return; case 1: /* monadiques */ if (!filter(expr, q->filtre, &ca) || ca == NULL || !*ca) { break; } parse2(ca, presult); (*q->callop)(presult, NULL, NULL); return; case -1: /* parentheses */ if (!filter(expr, q->filtre, &ca) || ca == NULL || !*ca) { break; } parse2(ca, presult); return; case -2: /* constante hex, bin ou octale */ if (!filter(expr, q->filtre, &ca) || ca == NULL || !*ca) { break; } (*q->callop)(presult, NULL, ca); reverse(expr); return; case -3: /* label */ reverse(expr); if (checklabel(expr)) { cstlabel(presult, NULL, expr); reverse(expr); return; } break; } q += q->nxt; } /* Noop: c'est forcement un decimal ou une cst ascii */ if (isdigit(*expr)) { cstdecimal(presult, NULL, expr); reverse(expr); } else if (*expr == '\'' || *expr == '\"') { cstascii(presult, NULL, expr); reverse(expr); } else { crasm_error("syntax error in an expression"); } } struct result* parse(char* expr) { char* dummy; if (!expr || !*expr) { crasm_error("expression expected"); } if (filter(expr, "(?)", &dummy)) { crasm_warning("external parenthesis ignored"); } reverse(expr); parse2(expr, &calcresult); reverse(expr); return &calcresult; } crasm-1.11/src/pseudos.c000066400000000000000000000211201475737230500151670ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* CRASM.C: pseudos.c execution des pseudos standard ( sauf IF..MACRO..CPU ) */ #include "dcl.h" #include "label.h" #include "cpu.h" extern int thiscall; /* label = value */ int Xequ(int modifier, char* label, char* mnemo, char* oper) { struct result* r; struct label* l; r = parse(oper); r->flags &= ~(UNDEF | USED | NOREDEF); if (r->type == L_ABSOLUTE || r->type == L_RELATIVE) { if (macrolevel == 0 || asmflags & F_MACROLIST_ON) { if (lpos == 0) { position(2); outputaddr(r->value); } } } l = deflabel(label, r->flags, r->type, r->value); l->modifier = r->modifier; l->ptr = r->ptr; return 0; } void checktype(struct result* r, int type) { if (r->type == type) { return; } switch (r->type) { case L_MNEMO: crasm_error("illegal use of a mnemonic"); break; case L_MACRO: crasm_error("illegal use of a macro"); break; case L_ABSOLUTE: crasm_error("illegal use of an absolute reference"); break; case L_RELATIVE: crasm_error("illegal use of a relative reference"); break; case L_REGS: crasm_error("illegal use of registers"); break; case L_DIRECTBIT: crasm_error("illegal use of direct bit reference"); break; default: crasm_error("Bad expression type"); } } static void stocke(char* s, int modifier) { unsigned long mask = 0; struct result* r; r = parse(s); checktype(r, L_ABSOLUTE); switch (modifier) { case 1: mask = 0xffffff00; insert8(r->value); break; case 2: mask = 0xffff0000; asmflags ^= F_LOHI; insert16(r->value); asmflags ^= F_LOHI; break; case 3: mask = 0xffff0000; insert16(r->value); break; case 4: mask = 0; insert32(r->value); break; } if (r->value & mask) { crasm_warning("Operand overflow"); } } /* DCB DCW DCL datas */ int Xdc(int modifier, char* label, char* mnemo, char* oper) { char* s1; char* s2; while (filter(oper, "?_,_?", &s1, &s2)) { oper = s2; stocke(s1, modifier); } stocke(oper, modifier); return 0; } /* DS size ou DS size,fill */ int Xds(int modifier, char* label, char* mnemo, char* oper) { struct result* r; register int i; register int init; char* s1; char* s2; if (filter(oper, "?_,_?", &s1, &s2)) { oper = s1; r = parse(s2); checktype(r, L_ABSOLUTE); init = r->value; if (init & 0xffffff00) { crasm_warning("multiple byte initialiser"); } } else { init = 0; } r = parse(oper); checktype(r, L_ABSOLUTE); i = r->value; while (i--) { insert8(init); } advance = r->value; return 0; } /* NAM title */ int Xnam(int modifier, char* label, char* mnemo, char* oper) { if (!oper) { crasm_error("need an operand"); } settitle(oper); return 0; } /* ASC string */ int Xasc(int modifier, char* label, char* mnemo, char* oper) { if (oper == NULL) { crasm_error("Need an operand"); } register char* s; register char r; register char delimiter; s = oper; delimiter = *s; if (delimiter != '\'' && delimiter != '\"') { crasm_error("Bad operand syntax"); } while ((r = *++s) != delimiter) { if (r == '\\') { switch (*++s) { case 't': r = '\t'; break; case 'n': r = '\n'; break; case 'r': r = '\r'; break; case '0': r = 0; break; case '\'': case '\"': case '\\': r = *s; break; default: crasm_error("Bad \\X character"); } } insert8(r); } if (*++s) { crasm_error("syntax error"); } return 0; } /* CODE or DUMMY */ extern int segment; int Xcode(int modifier, char* label, char* mnemo, char* oper) { if (oper && *oper) { crasm_error("no operand for CODE pseudo"); } segment = ++thiscall; asmflags |= F_CODE_ON; return 0; } int Xdummy(int modifier, char* label, char* mnemo, char* oper) { if (oper && *oper) { crasm_error("no operand for DUMMY pseudo"); } segment = ++thiscall; asmflags &= ~ F_CODE_ON; return 0; } /* LIST MLIST CLIST ILIST ON ou OFF */ int Xlist(int modifier, char* label, char* mnemo, char* oper) { if (filter(oper, "_ON_")) { if (!(asmflags & F_NOLIST)) { asmflags |= F_LIST_ON; } } else if (filter(oper, "_OFF_")) { asmflags &= ~ F_LIST_ON; } else { crasm_error("please: use option ON or OFF"); } return 0; } int Xmlist(int modifier, char* label, char* mnemo, char* oper) { if (filter(oper, "_ON_")) { asmflags |= F_MACROLIST_ON; } else if (filter(oper, "_OFF_")) { asmflags &= ~ F_MACROLIST_ON; } else { crasm_error("please: use option ON or OFF"); } return 0; } int Xclist(int modifier, char* label, char* mnemo, char* oper) { if (filter(oper, "_ON_")) { asmflags |= F_IFLIST_ON; } else if (filter(oper, "_OFF_")) { asmflags &= ~ F_IFLIST_ON; } else { crasm_error("please: use option ON or OFF"); } return 0; } int Xilist(int modifier, char* label, char* mnemo, char* oper) { if (filter(oper, "_ON_")) { asmflags |= F_INCLUDELIST_ON; } else if (filter(oper, "_OFF_")) { asmflags &= ~ F_INCLUDELIST_ON; } else { crasm_error("please: use option ON or OFF"); } return 0; } /* PAGE ou PAGE plen,llen */ int Xpage(int modifier, char* label, char* mnemo, char* oper) { char* s1; char* s2; register struct result* r; register int plen; if (!oper) { outputEOP(); return 0; } if (!filter(oper, "?_,_?", &s1, &s2)) { crasm_error("syntax: PAGE or PAGE plen,llen "); } checktype(r = parse(s1), L_ABSOLUTE); plen = r->value; checktype(r = parse(s2), L_ABSOLUTE); setpage(plen, r->value); return 0; } /* Xskip SKIP nn | SKIP PAGE */ int Xskip(int modifier, char* label, char* mnemo, char* oper) { register struct result* rr; register int r; checktype(rr = parse(oper), L_ABSOLUTE); r = rr->value; if (r > 100 || r < 0) { crasm_warning("are you sure ?"); } else { while (r--) { outputEOL(); } } return 0; } /* Xoutput OUTPUT SCODE | OUTPUT HEX */ int Xoutput(int modifier, char* label, char* mnemo, char* oper) { asmflags &= ~(F_CODE_HEX | F_CODE_SCODE); if (filter(oper, "_HEX_")) { asmflags |= F_CODE_HEX; } else if (filter(oper, "_SCODE_")) { asmflags |= F_CODE_SCODE; } else { crasm_error("please, use options SCODE or HEX"); } return 0; } /* Xalign ALIGN EVEN | ALIGN ODD */ int Xalign(int modifier, char* label, char* mnemo, char* oper) { extern unsigned long pc; if (filter(oper, "_EVEN_")) { if (pc & 1) { insert8(0); } } else if (filter(oper, "_ODD_")) { if (!(pc & 1)) { insert8(0); } } else { crasm_error("please, use options EVEN or ODD"); } return 0; } /* CPU cpuname */ int Xcpu(int modifier, char* label, char* mnemo, char* oper) { struct cpulist* q; char* a; extern struct cpulist cpulist[]; if (!oper) { crasm_error("Need CPU name"); } if (asmflags & F_CPU_GV) { crasm_error("One CPU only!"); } q = cpulist; while (q->name) { if (filter(oper, q->name, &a, &a, &a, &a)) { break; } else { q++; } } if (! q->name) { crasm_error("Unknown CPU name"); } if (passnumber == 2) { asmflags |= F_CPU_GV; } (*q->init)(q->code); return 0; } /* FAIL error */ int Xfail(int modf, char* label, char* mnemo, char* oper) { if (oper && *oper) { crasm_error(oper); } else { crasm_error("Fail instruction"); } return 0; } crasm-1.11/src/scode.c000066400000000000000000000077621475737230500146220ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* CRASM: scode.c sorties du scode LYB 9/87 */ #include "dcl.h" unsigned long pc; unsigned long codelen; unsigned long rawstart; int rawnumber; int rawextended; char raw[16]; extern int includelevel; void setpc(long unsigned int addr) { if (addr != pc) { flushscoderaw(); rawstart = pc = addr; rawnumber = 0; } } void insert8(unsigned char x) { if (!(asmflags & F_ORG_GV)) { crasm_error("no org given"); } if (!(asmflags & F_NOCODE)) { if (scode == NULL) { scode = fopen(scodename, "w"); if (scode == NULL) { crasm_fatal("can't open scode file"); } rawextended = 0; } } if (asmflags & F_CODE_ON) { if (scode != NULL) { if (rawnumber >= 16) { flushscoderaw(); } raw[rawnumber++] = x; } codelen++; outputbyte(x); } advance++; pc++; } void insert16(short unsigned int x) { if (asmflags & F_LOHI) { insert8(x); insert8(x >> 8); } else { insert8(x >> 8); insert8(x); } } void insert24(unsigned int x) { if (asmflags & F_LOHI) { insert16(x); insert8(x >> 16); } else { insert8(x >> 16); insert16(x); } } void insert32(unsigned int x) { if (asmflags & F_LOHI) { insert16(x); insert16(x >> 16); } else { insert16(x >> 16); insert16(x); } } static unsigned char checksum; static void scodebyte(unsigned char b) { checksum += b; fputc(hexa[(b >> 4) & 0xf], scode); fputc(hexa[b & 0xf], scode); if (ferror(scode)) { fileerror(scodename); } } void closescodefile(void) { flushscoderaw(); if (asmflags & F_CODE_HEX) { fputs(":00000001FF\n", scode); } else { fputs("S9030000FC\n", scode); } if (scode) { fclose(scode); } } void flushscoderaw(void) { register int i; if (rawnumber) { if (asmflags & F_CODE_HEX) { if ((rawextended ^ rawstart) & 0xffff0000) { fputs(":02000004", scode); checksum = (unsigned char)(0xFF + 0x02 + 0x04); scodebyte(rawstart >> 24); scodebyte(rawstart >> 16); scodebyte(~checksum); fputc('\n', scode); rawextended = rawstart; } fputc(':', scode); checksum = 0xFF; scodebyte(rawnumber); scodebyte(rawstart >> 8); scodebyte(rawstart); scodebyte(0x00); } else { fputc('S', scode); checksum = 0; if (rawstart & 0xff000000) { fputc('3', scode); scodebyte(rawnumber + 5); scodebyte(rawstart >> 24); scodebyte(rawstart >> 16); } else if (rawstart & 0xff0000) { fputc('2', scode); scodebyte(rawnumber + 4); scodebyte(rawstart >> 16); } else { fputc('1', scode); scodebyte(rawnumber + 3); } scodebyte(rawstart >> 8); scodebyte(rawstart); } for (i = 0; i < rawnumber; i++) { scodebyte(raw[i]); } scodebyte(~ checksum); fputc('\n', scode); } rawstart = pc; rawnumber = 0; } crasm-1.11/src/stdvocabulary.c000066400000000000000000000043471475737230500164030ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* CRASM.C stdvocabulary.c definition des pseudos standard */ #include "dcl.h" #include "label.h" #define defpseudo(n,f,c) {0,0,n,f|NOREDEF,L_MNEMO,0,c,0}, #define defspecial(n,f,c,m) {0,0,n,f|NOREDEF,L_MNEMO,m,c,0}, struct label pseudos[] = { defpseudo("EQU", DEFLABEL, Xequ) defpseudo("ASC", 0, Xasc) defpseudo("ALIGN", 0, Xalign) defpseudo("CLIST", NOLABEL, Xclist) defpseudo("CODE", NOLABEL, Xcode) defpseudo("CPU", NOLABEL, Xcpu) defspecial("DB", 0, Xdc, 1) defspecial("DDB", 0, Xdc, 2) defspecial("DL", 0, Xdc, 4) defspecial("DW", 0, Xdc, 3) defpseudo("DUMMY", NOLABEL, Xdummy) defpseudo("DS", 0, Xds) defpseudo("ELSE", NOLABEL | DEFCOND, Xelse) defpseudo("ENDC", NOLABEL | DEFCOND, Xendc) defpseudo("ENDM", NOLABEL | DEFMACRO, Xendm) defpseudo("EXITM", NOLABEL | DEFMACRO, Xexitm) defpseudo("FAIL", NOLABEL, Xfail) defpseudo("IF", NOLABEL | DEFCOND, Xif) defpseudo("ILIST", NOLABEL, Xilist) defpseudo("INCLUDE", NOLABEL, Xinclude) defpseudo("LIST", NOLABEL, Xlist) defpseudo("MACRO", DEFLABEL | DEFMACRO, Xmacro) defpseudo("MLIST", NOLABEL, Xmlist) defpseudo("NAM", NOLABEL, Xnam) defpseudo("PAGE", NOLABEL, Xpage) defpseudo("OUTPUT", NOLABEL, Xoutput) defpseudo("SKIP", NOLABEL, Xskip) { (void*) -1, (void*) -1, {0}, 0, 0, 0, 0, 0 } }; crasm-1.11/src/version.h000066400000000000000000000000341475737230500152000ustar00rootroot00000000000000#define CRASMVERSION "1.11" crasm-1.11/src/xref.c000066400000000000000000000063761475737230500144710ustar00rootroot00000000000000/* Copyright (C) 1987- Leon Bottou * * This is free documentation; 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. * * The GNU General Public License's references to "object code" * and "executables" are to be interpreted as the output of any * document formatting or typesetting system, including * intermediate and printed output. * * This manual 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 manual. Otherwise check the web site * of the Free Software Foundation at http://www.fsf.org. */ /* CRASM: xref.c sorties des references croisees LYB 9/87 */ #include "dcl.h" #include "label.h" extern unsigned long pc; extern unsigned long codelen; extern int segment; #define RECLEN (LABLEN+13) char* msgs[] = { "Undefined", "Mnemonic", "Macro", "Abs", "Rel", "Register(s)", "Bit%d" }; void printlabel(struct label* label) { char buffer[RECLEN + 2]; char* s; char* b; int newpos; register int i; if (lpos + RECLEN >= llen) { outputEOL(); } newpos = lpos + RECLEN; if (label->type != L_ABSOLUTE && label->type != L_RELATIVE) { if (label->flags & NOREDEF) { return; } } if (label->type < 0) { label->type = 1; } if (label->name[0] == '*' || label->name[0] <= '9') { return; } if ((label->flags & UNDEF) && !(label->flags & FORWARD)) { label->type = 0; } s = label->name; i = label->type; i = (i == 3 || i == 4 || i == 6); if (!(label->flags & USED)) { outputcar('?'); } else if (label->flags & FORWARD) { outputcar('^'); } else { outputcar(' '); } if (i) { outputaddr(label->value); } sprintf(buffer, msgs[label->type], label->modifier); position(newpos - LABLEN - 2 - strlen(buffer)); output(buffer); position(newpos - LABLEN - 1); b = buffer; for (i = 0; i < LABLEN && *s ; i++) { *b++ = *s++; } *b = 0; output(buffer); position(newpos); } static void xref2(struct label* label) { if (label) { xref2(label->left); printlabel(label); xref2(label->right); } } void result(void) { extern int errnumber; extern int warnnumber; char buffer[40]; if (plen - ppos < 10) { outputEOP(); outputEOL(); outputEOL(); } outputEOL(); sprintf(buffer, "ERRORS: %4d", errnumber); output(buffer); outputEOL(); sprintf(buffer, "WARNINGS: %4d", warnnumber); output(buffer); outputEOL(); outputEOL(); if (!errnumber) { output("Successful assembly..."); outputEOL(); sprintf(buffer, " Last address %8lx (%ld)", pc - 1, pc - 1); output(buffer); outputEOL(); sprintf(buffer, " Code length %8lx (%ld)", codelen, codelen); output(buffer); outputEOL(); } else { output("No code generated..."); outputEOL(); } } void xref(void) { outputEOP(); xref2(lroot); outputEOL(); outputEOP(); } crasm-1.11/test/000077500000000000000000000000001475737230500135355ustar00rootroot00000000000000crasm-1.11/test/Makefile000066400000000000000000000004551475737230500152010ustar00rootroot00000000000000TEST_SOURCES := $(wildcard *.asm) TEST_OUTPUT := $(TEST_SOURCES:.asm=.out) %.out : %.asm mkdir -p test_output ../src/crasm -o test_output/$@ -l $< @diff test_output/$@ reference_output/$@ || (echo "Output '$@' does not match expected!"; exit 1 ) test: ${TEST_OUTPUT} clean: rm -rf test_output crasm-1.11/test/copy.6800.asm000066400000000000000000000007431475737230500156110ustar00rootroot00000000000000;;; Author: Leon Bottou ;;; Public Domain. cpu 6800 * = $8000 begin = $40 dest = $42 len = $44 ldx #$4000 stx begin ldx #$1430 stx len ldx #$6000 stx dest jsr copy wai code ; copy LEN bytes from BEGIN to DEST copy ldx begin sts begin txs ldx dest ldab len+1 ldaa len addb dest+1 adca dest stab dest+1 staa dest .1 cpx dest beq .2 pula staa 0,x inx bra .1 .2 tsx lds begin stx begin clr len clr len+1 rts code crasm-1.11/test/forth.6801.asm000066400000000000000000000103061475737230500157560ustar00rootroot00000000000000;;; Author: Leon Bottou ;;; Public Domain. ; Beginnings of a forth kernel. ; Good test for macros. ; ; http://www.forth.org/ ; http://www.zetetics.com/bj/papers/moving1.htm cpu 6801 mlist off page 0,132 * = $1000 smudge = 1<<7 precedence = 1<<6 keep = 1<<5 ;; ********************************** ;; -- create INVOCNAME, WORDNAME [, FLAGS] ;; Create a forth word WORDNAME into vocabulary INVOCNAME ;; This macro outputs the word header and defines useful labels ;; nfa_WORDNAME - address of header ;; lfa_WORDNAME - address of pointer to previous word in vocabulary ;; cfa_WORDNAME - address of executable data (just after header) create macro .start = * if \3 nfa_\2 db .len | smudge | \3 else nfa_\2 db .len | smudge endc asc "\2" lfa_\2 dw lstw_\1 lstw_\1 = .start cfa_\2 = * .len = lfa_\2-nfa_\2 endm ;; ********************************** ;; -- createvoc INVOCNAME,VOCNAME ;; Create a forth vocabulary VOCNAME in vocabulary INVOCNAME ;; This macro outputs the word header and defines useful labels ;; nfa_VOCNAME - address of word header ;; lfa_VOCNAME - address of pointer to previous word in voc INVOCNAME ;; cfa_VOCNAME - address of word executable data (jsr dovoc) ;; pfa_VOCNAME - address of vocabulary data for VOCNAME ;; lst_VOCNAME - address of pointer to last word in vocabulary ;; vlnk_VOCNAME - address of pointer to parent vocabulary. ;; The following symbol is modified whenever ;; a word is added into the vocabulary VOCNAME ;; lstw_VOCNAME - address of last word in vocabulary VOCNAME ;; until one calls endvoc createvoc macro lstw_\2 = pfa_\1 create \1,\2 jsr dovoc pfa_\2 db smudge|1,' ' lst_\2 dw 0 vlnk_\2 dw pfa_\1 endm ;; ********************************** ;; -- endvoc VOCNAME ;; Terminates definition of vocabulary VOCNAME ;; This sets the value of pointer at address lst_VOCNAME ;; No words should be added to the vocabulary. endvoc macro asc "LYB Forth." .loc = * * = lst_\1 dw lstw_\1 * = .loc endm ;; ********************************** ;; -- createforth ;; Creates the initial vocabulary named FORTH. createforth macro lstw_forth = 0 nfa_forth db 6|smudge asc "forth" lfa_forth = 0 cfa_forth jsr dovoc pfa_forth db smudge|1,' ' lst_forth db 0 vlnk_forth dw 0 endm ;; ********************************** ;; -- start, end, compile ;; These macros are used to define a forth word. ;; Usage: ;; create INVOCNAME, WORDNAME ;; start ;; compile WORDNAME ;; compile WORDNAME ;; ... ;; end ;; What about constants... start macro jsr docol endm end macro dw endcol endm compile macro dw cfa_\1 endm ;; ********************************** ;; -- docol, endcol, next ;; The forth interpreter engine. ;; The forth data stack is the 6801 stack. ip = $80 ; instruction pointer rp = $82 ; return stack pointer dp = $84 ; used to save the data stack pointer ;; docol - start interpreting a forth thread docol ldd ip ldx rp std 0,x dex dex stx rp pulx stx ip ldx ,x jmp ,x ;; endcol -- return from interpreting a forth thread endcol ldx rp inx inx stx rp ldx ,x inx inx stx ip ldx ,x jmp ,x ;; next -- return from assembly code primitive next ldx ip inx inx stx ip ldx ,x jmp ,x ;; dovoc -- undefined yet dovoc rts ;; ********************************** ;; Forth words code createforth code create forth,dup pulx pshx pshx jmp next code create forth,drop pulx jmp next code create forth,ndrop pulx .1 beq .2 pula pula dex bra .1 .2 jmp next code create forth,swap pulx pula pulb pshx pshb psha jmp next code create forth,pick pula pulb lsrd sts dp addd dp std dp ldx dp ldx ,x pshx jmp next code create forth,over pula pulb pulx pshx pshb psha pshx jmp next code create forth,rot pulx stx dp pulx pula pulb pshx ldx dp pshx pshb psha jmp next ;; USER VOCABULARY code createvoc forth,uservoc code create uservoc,dupdrop,precedence start compile dup compile drop end endvoc uservoc ; Terminate vocabulary USERVOC endvoc forth ; Terminate vocabulry FORTH crasm-1.11/test/math16.6502.asm000066400000000000000000000036571475737230500157450ustar00rootroot00000000000000;;; Author: Leon Bottou ;;; Public Domain. cpu 6502 ; 16 bit calculus functions. ; Two pseudoregisters: ACC, ARG ; Four temporary bytes: TEMP dummy * = $20 acc ds 2 arg ds 2 temp ds 4 movi macro lda #(\1) & $ff sta \2 lda #(\1) >> 8 sta (\2)+1 endm movm macro lda \1 sta \2 lda (\1)+1 sta (\2)+2 endm * = $8000 code add16 lda acc ; ACC <- ACC + ARG clc adc arg sta acc lda acc+1 adc arg+1 sta acc+1 rts clr16 lda #0 ; clear ACC sta acc sta acc+1 .1 rts abs16 bit acc+1 ; absolute value of ACC bpl .1 neg16 lda #0 ; negate ACC sec sbc acc sta acc lda #0 sbc acc+1 sta acc+1 rts neg16a lda #0 ; negate ARG sec sbc arg sta arg lda #0 sbc arg+1 sta arg+1 rts sub16 lda acc ; ACC <- ACC - ARG sec sbc arg sta acc lda acc+1 sbc arg+1 sta acc+1 rts code ovfl bit .ov1 .ov1 rts code muls16 lda acc+1 ; ACC <- ACC * ARG eor arg+1 sta temp+3 bit arg+1 bpl .0 jsr neg16a .0 jsr abs16 lda #$80 sta temp+1 lda #0 sta temp sta temp+2 .1 lsr acc+1 lsr acc bcc .2 pha lda temp+2 clc adc arg sta temp+2 pla adc arg+1 .2 ror ror temp+2 ror temp+1 ror temp bcc .1 ora temp+2 php movm temp,acc plp bne ovfl bit acc+1 bmi ovfl bit temp+3 bpl .3 jsr neg16 .3 rts code divmod movm acc,temp ; ACC <- ACC / ARG (unsigned) lda #$01 ; TEMP+2 <- ACC % ARG (unsigned) sta acc asl sta temp+2 sta temp+3 sta acc+1 lda arg ora arg beq ovfl .1 asl temp rol temp+1 rol temp+2 rol temp+3 lda temp+2 cmp arg lda temp+3 sbc arg+1 bcc .2 sta temp+3 lda temp+2 sbc arg sta temp+2 sec .2 rol acc rol acc+1 bcc .1 rts code divs16 lda acc+1 ; ACC <- ACC / ARG eor arg+1 pha bit arg+1 bpl .0 jsr neg16a .0 jsr abs16 jsr divmod pla bpl .1 jmp neg16 .1 rts code mod16 lda acc+1 ; ACC <- ACC % ARG pha bit arg+1 bpl .0 jsr neg16a .0 jsr abs16 jsr divmod movm temp+2,acc pla bpl .1 jmp neg16 .1 rts crasm-1.11/test/memcpy.6800.asm000066400000000000000000000025731475737230500161340ustar00rootroot00000000000000 page 66,264 cpu 6800 * = $1000 ; memcpy -- ; Copy a block of memory from one location to another. ; Called as a subroutine, note return to saved PC addr on exit ; Entry parameters ; cnt - Number of bytes to copy ; src - Address of source data block ; dst - Address of target data block cnt dw $0000 ; sets aside space for memory addr src dw $0000 ; sets aside space for memory addr dst dw $0000 ; sets aside space for memory addr memcpy ldab cnt+1 ;Set B = cnt.L beq check ;If cnt.L=0, goto check loop ldx src ;Set IX = src ldaa ,x ;Load A from (src) inx ;Set src = src+1 stx src ldx dst ;Set IX = dst staa ,x ;Store A to (dst) inx ;Set dst = dst+1 stx dst decb ;Decr B bne loop ;Repeat the loop stab cnt+1 ;Set cnt.L = 0 check tst cnt+0 ;If cnt.H=0, beq done ;Then quit dec cnt+0 ;Decr cnt.H ; loop back and do 256*(cnt.H+1) more copies (B=0) bra loop ;Repeat the loop done rts ;Return crasm-1.11/test/modem.6801.asm000066400000000000000000000532011475737230500157360ustar00rootroot00000000000000;;; Author: Leon Bottou ;;; Public Domain. ; Ceci est le code source du programme ; contenu dans un modem pilote par 6801. ; ; Le processeur (Motorola 6801) ; - communiquait avec l'ordinateur par ; son propre port serie a 1200 ou 9600 bauds ; selon l'etat du switch INSP ; - communiquait avec une puce modem EFCIS ; via un ACIA 6850 ; - Ses ports // controlaient divers ; parametres du circuit modem, et une LED ; ; Il y avait en outre ; - 4k de ROM (2532) de $f000 a $ffff ; - 2k de RAM CMOS (6116) de $d800 a $dfff ; - Une horloge temps reel 6818 sauvegardee ; ; Le programme ci dessous contient un Moniteur ; Hexa (Apple][ like) avec mini-assembleur ; et desassembleur, et le programme de gestion ; du modem. Au reset, le CPU branche sur l'un ou ; l'autre, selon l'etat d'un switch INMOD. ; Cible: TI ou Motorola 2532 ; placee aux adresses $F000->$FFFF ; Declarations page 0,132 output scode cpu 6801 fdb = dw ; equivalence de mnemoniques fcb = db fcc = db ; pour ne pas trop modifier... org macro * = \1 endm ; quelques registres du 6801 ; et leur signification ici. ddr1 equ $00 ddr2 equ $01 dr1 equ $02 ; /XRTS,HANG,/CTS,TEST,MC/BC,/CD,INMOD,INSP dr2 equ $03 ; b0: /LEDR tcsr equ $8 ; ICF,OCF,TOF,EICI,EOCI,ETOI,IEDG,OLVL tim equ $9 ocr equ $b rmcr equ $10 trcsr equ $11 ; RDRF,ORFE,TDRE,RIE,RE,TIE,TE,WU rdr equ $12 tdr equ $13 ; Les adresses de l'ACIA 6850 aciacr equ $bffe ; crW: RIE,0,TIE,P,P,P,D,D ( 01001 ) aciadr equ $bfff ; crR: IRQ,PE,OV,FE,/CTS,/DCD,TDRE,RDRF ; Deux octets de ram sauvegardee ; dans l'horloge 6818 sav1 equ $9fce ; RamOk:$87 sav2 equ $9fcf ; /LF,/XonXoff,RTS,0,ECHO,HALF,TEST,MCBC ; Les registres du 6818 hbase equ $9fc0 rega equ $9fca ; UIP,div2-0(010) rs3-0(0000) regb equ $9fcb ; SET,PIE,AIE,UIE,SQWE,DM,24/12,DSE regc equ $9fcc ; IRQF,PF,AF,UF, 0000 regd equ $9fcd ; VRT,0000000 ; Les adresses de base de : ; la RAM CMOS 6116 ; la RAM du 6818 sram equ $d800 hram equ $9fd0 ; La queue d'entree dans la 6116 dgo equ $dfae xgo equ $dfac ; Le buffer de ligne pour le moniteur inbuf equ $dfb1 endbuf equ $dfff ; Quelques emplacement dans ; la ram du 6801 possav equ $96 ocfv equ $80 tofv equ $82 icfv equ $84 nmiv equ $86 flashled equ $88 counter equ $88 flag equ $89 ; FLSH,-,+,.,:,sz2-0 mode equ $89 posxin equ $8a posin equ $8c rcvxin equ $8b rcvin equ $8d abort equ $1d xinmask equ $1f inmask equ $7f xsav equ $8e r0 equ $90 r1 equ $92 r2 equ $94 checksum equ $9e aciamode equ $9f ; dont la queue d'entree du modem, ; et la pile CPU xinqueue equ $a0 inqueue equ $df00 stkbase equ $ff ; Les vecteurs d'interruption org $fff0 fdb sciirq fdb ledirq fdb ocfirq fdb icfirq fdb aciairq fdb swiirq fdb nmiirq fdb reset ; Le programme lui meme org $f000 msga asc "\n\rMoniteur LYB.\0" msgb asc "Erreur\0" msgc asc "Erreur de Checksum\0" msgd asc "OVERFLOW\n\r\0" msgswi asc "\n\rSWI: SP P A B X\0" msgwr asc "S9030000FC\0" mydummy rti ocfirq ldx ocfv jmp 0,x icfirq ldx icfv jmp 0,x nmiirq ldx nmiv jmp 0,x swiirq ldx #msgswi jsr outmsg tsx ldx 5,x jsr prx jsr outsp tsx jsr prx jsr outsp ldab 0,x jsr prb jsr outsp ldab 2,x jsr prb ldab 1,x jsr prb jsr outsp ldx 3,x jsr prx jsr outcr jmp monloop2 ; Reset general reset lds #stkbase ldx #mydummy stx ocfv stx icfv stx nmiv stx tofv clra staa flashled staa posin staa posxin staa rcvin staa rcvxin ldaa sav1 cmpa #$87 beq reset2 clra staa sav2 reset2 anda regd anda #$80 staa flag oraa #$7 staa sav1 sei ldaa #$11 staa ddr2 ldaa #$f8 staa ddr1 ldaa #%10000000 staa dr1 ldaa #$01 staa dr2 ldaa #%011 staa aciacr ldaa #%01001 staa aciacr staa aciamode ldaa #%11010 staa trcsr ldab dr1 ldaa #%0110 ; 1200 bauds bitb #$01 beq reset3 ldaa #%0101 ; 9600 bauds reset3 staa rmcr ldaa #%0101 staa tcsr cli ldx #inbuf-1 reset1 inx clr 0,x cpx #endbuf bne reset1 bitb #$02 beq reset5 reset4 jmp modem reset5 jmp monloop ; SP de controle des irq eixin ldab #$80 orab aciamode bra setxcr dixin ldab #$7f andb aciamode setxcr stab aciamode stab aciacr rts ; SciIrq sciirq ldaa rcvin inca tab suba posin anda #inmask beq ovfl ldx #inqueue andb #inmask abx stab rcvin ldab trcsr ldab rdr stab 0,x cmpa #inmask-31 bne sciret cli ldab sav2 bitb #$40 bne noxoff ldaa #'S'-$40 jsr out noxoff ldab sav2 bitb #$20 beq sciret sei ldab dr1 orab #$20 stab dr1 sciret rti ovfl sei ldx #msgd ovfl2 ldaa trcsr bita #$20 beq ovfl2 ldaa 0,x beq sciret staa tdr inx bra ovfl2 ; Aciairq aciairq ldab rcvxin incb andb #xinmask tba suba posxin anda #xinmask beq ovfl ldx #xinqueue abx stab rcvxin ldaa aciacr ldaa aciadr staa 0,x rti ; StdIn in bsr intst beq in rdret rts ; Intst intst ldab posin tba suba rcvin nega anda #inmask beq rdret rdin incb andb #inmask stx xsav ldx #inqueue abx cmpa #$8 bne rdin2 ldaa sav2 bita #$40 bne noxon ldaa #'Q'-$40 jsr out noxon ldaa sav2 bita #$20 beq rdin2 sei ldaa dr1 anda #$df staa dr1 cli rdin2 sei inc posin ldaa 0,x ldx xsav bra retour ; Xout xout2 cli xout sei ldab #$2 bitb aciacr beq xout2 ldab aciacr staa aciadr cli rts ; Xin xin bsr xintst beq xin xinret rts ; Xintst xintst ldab posxin tba suba rcvxin anda #xinmask beq xinret incb andb #xinmask ldx #xinqueue abx sei stab posxin ldaa 0,x retour cli ldab #$ff rts ; StdOut out2 sei out cli ldab #$20 bitb trcsr beq out2 ldab trcsr staa tdr cli rts ; OUT ceci et cela outcr ldaa sav2 bmi outcr2 ldaa #$a bsr out outcr2 ldaa #$d bra out outbs ldaa #$08 bsr out bsr outsp ldaa #$08 bra out outmsg ldaa 0,x beq outcr bsr out inx bra outmsg outt ldaa #'-' bra out outsp ldaa #$20 bra out out2p ldaa #':' bra out prx stx xsav ldab xsav bsr prb ldab xsav+1 prb pshb addb checksum stab checksum pula psha lsra lsra lsra lsra bsr prb2 pula prb2 anda #$f oraa #$30 cmpa #$3a bcs prb3 adda #$7 prb3 bra out heure jsr outcr ldab sav1 ldaa #$20 cmpb #$87 beq heur1 ldaa #'#' heur1 jsr out ldx #hbase heur2 ldaa rega bmi heur2 ldab 7,x bsr prb bsr outt ldab 8,x bsr prb bsr outt ldab #$19 bsr prb ldab 9,x bsr prb bsr outsp ldab 4,x bsr prb bsr out2p ldab 2,x bsr prb bsr out2p ldab 0,x bra prb ; IRQ: ledirq 1/20s ledirq inc flashled ldaa tcsr ldx tim ldaa #$8 bita flashled bne led2 ldaa flag bmi tofirq ldaa #$1 oraa dr2 bra led3 led2 ldaa #$fe anda dr2 led3 staa dr2 tofirq ldx tofv jmp 0,x ; MONITEUR: rdline rdline2 ldaa #'\\' jsr out rdline jsr outcr rdnoret ldaa inbuf-1 jsr out ldx #inbuf rdloop jsr in cmpa #abort beq rdline2 cmpa #$09 bne rdline1 ldaa 0,x beq rdloop rdline1 cmpa #$08 bne rdline3 cpx #inbuf beq rdline jsr outbs dex bra rdloop rdline3 cmpa #$0a beq rdloop cmpa #$0d bne rdline4 rdend clr 0,x jmp outcr rdline4 cpx #endbuf bcc rdloop jsr out staa 0,x inx bra rdloop ; Conversion en majuscules maj cmpa #'a' bcs maj2 cmpa #'z' bhi maj2 suba #$20 maj2 rts ; Lecture d'un hhhh readhex ldaa flag anda #$f8 staa flag ldaa 0,x cmpa #'\'' bne readhex2 clr r1 ldaa 1,x staa r1+1 inc flag ldaa 2,x inx inx readhex5 inc flag ldab flag bitb #$70 bne readhex6 bitb #$6 beq readhex6 ldd r1 std r0 readhex6 ldaa 0,x inx bra maj readhex2 ldaa 0,x jsr maj ldab #$4 bitb flag bne readhex5 jsr conv bcc readhex5 ldaa #$7 bita flag bne readhex3 clra staa r1 staa r1+1 readhex3 inc flag aslb aslb aslb aslb ldaa #$4 readhex4 aslb rol r1+1 rol r1 deca bne readhex4 inx bra readhex2 conv tab subb #$30 cmpb #$11 bcc conv2 cmpb #$a rts conv2 subb #$7 cmpb #$10 rts ; MONITEUR boucle et xeqline monloop ldx #msga jsr outmsg monloop2 lds #stkbase ldaa #'*' staa inbuf-1 jsr rdline ldx inbuf cpx #$4154 bne goxeq jsr hayes bra monloop2 goxeq jsr xeqline bra monloop2 xeqline ldx #inbuf stx possav ldaa flag anda #$80 staa flag xeq2 ldx possav jsr readhex stx possav ldx #jtable xeq3 cmpa 0,x beq xeq5 tst 0,x beq err inx inx inx bra xeq3 err ldx #msgb jmp outmsg xeq5 ldx 1,x ldab flag tba anda #$80 staa flag jsr 0,x bra xeq2 ; Table des commandes jtable fcb 'H' fdb heure fcb ' ' fdb space fcb '?' fdb ascii fcb '.' fdb point fcb 'G' fdb go fcb 'R' fdb read fcb 'W' fdb write fcb ':' fdb patchmode fcb 'X' fdb modem fcb '>' fdb prr2 fcb '+' fdb plus fcb '-' fdb moins fcb 'M' fdb move fcb '<' fdb transf fcb 'Y' fdb goram fcb '=' fdb setregs fcb 'L' fdb dasm fcb '!' fdb masm fcb 0 fdb cr ; Commandes moniteur cr pula pula ldx possav dex cpx #inbuf bne space ldd r0 orab #$f std r1 dump2 ldaa r0+1 anda #$f bne dump3 dump ldx r0 jsr outcr jsr prx jsr outt dump3 jsr outsp ldx r0 stx r2 ldab 0,x jsr prb jsr nxtr0 bcs dump2 rts nxtr2 ldx r2 inx stx r2 nxtr0 ldd r0 ldx r0 inx stx r0 subd r1 rts point ldaa #$10 bra orflag plus ldaa #$20 bra orflag moins ldaa #$40 orflag oraa flag staa flag space2 rts space tba anda #$88 staa flag bitb #$6 beq space2 bitb #$8 bne patch bitb #$20 bne xplus bitb #$40 bne xmoins bra dump patch ldx r2 ldaa r1+1 staa 0,x bitb #$4 beq patch2 ldd r1 std 0,x inx patch2 inx stx r2 rts xplus ldd r0 addd r1 bra xarith xmoins ldd r0 subd r1 xarith std r0 std r1 ldx r0 ldaa #'=' jsr out jmp prx patchmode orab #$8 andb #$8f stab flag bitb #$6 beq patchmd2 ldd r0 std r2 patchmd2 rts prr2 ldx r2 jsr prx jmp out2p go ldaa #$7e staa r0-1 ldd dgo ldx xgo jsr r0-1 swi goram ldx r1 jmp 0,x move ldx r0 ldaa 0,x ldx r2 staa 0,x jsr nxtr2 bcs move rts transf bitb #6 beq transf2 ldd r0 std r2 transf2 rts ascii2 ldaa r0+1 anda #$1f bne ascii3 ascii ldx r0 jsr outcr jsr prx jsr outt ascii3 jsr outsp ldx r0 stx r2 ldab 0,x tba andb #$7f cmpb #$20 bcc ascii4 ldaa #'.' ascii4 jsr out jsr nxtr0 bcs ascii2 rts setregs bitb #$10 beq setacc ldd r1 std xgo setacc ldd r0 std dgo rts ; Transferts SCODE lenframe equ $98 bufbyte equ $99 address equ $9a write ldx r0 ldd r1 subd r0 tsta bne write1 cmpb #$f bcs write2 write1 ldab #$f write2 incb stab lenframe ldaa #'S' jsr out ldaa #'1' jsr out clr checksum ldab lenframe addb #$3 jsr prb jsr prx write3 ldab 0,x inx jsr prb dec lenframe bne write3 ldab checksum comb jsr prb jsr outcr2 dex stx r0 jsr nxtr0 bcs write ldx #msgwr jmp outmsg rberr pula pula readerr jsr err readerr2 jsr in cmpa #abort bne readerr2 rts readdone jsr in jsr conv bcs readdone rts rbyte jsr in jsr conv bcc rberr aslb aslb aslb aslb stab bufbyte jsr in jsr conv bcc rberr orab bufbyte tba adda checksum staa checksum rts read2 jsr in jsr conv bcs read2 read jsr in cmpa #$0a beq read cmpa #$0d beq read cmpa #'S' bne readerr jsr in jsr conv bcc readerr tstb beq read2 cmpb #$9 beq readdone clr checksum bsr rbyte subb #3 stab lenframe beq read2 bsr rbyte stab address bsr rbyte stab address+1 ldx address read3 bsr rbyte cpx r0 bcs read4 cpx r1 bhi read4 stab 0,x read4 inx dec lenframe bne read3 bsr rbyte ldab checksum comb beq read ldx #msgc jsr outmsg bra read ; Dessassembleur dasm bitb #$10 bne dasm4 bitb #$6 beq dasm2 ldd r0 std r2 dasm2 ldaa #$14 dasm3 psha jsr dasmins pula deca bne dasm3 rts dasm4 ldd r0 std r2 dasm5 jsr dasmins ldd r2 subd r1 bcs dasm5 rts ; Miniassembleur masm bitb #$6 beq masm2 ldd r0 std r2 masm2 ldx r2 jsr prx ldaa #'!' staa inbuf-1 jsr rdnoret ldx #inbuf-1 masm4 inx ldaa 0,x cmpa #$20 beq masm4 stx possav tsta beq masm3 jsr masmins bcs masm5 jsr dasmins bra masm2 masm5 jsr err bra masm2 masm3 jmp monloop2 ; Hayes msgh1 asc "ERROR\0" msgh2 asc "NO CONNECT\0" msgh3 asc "OK\0" msgh4 asc "\r\nEND OF CONNECTION\0" msghay asc "SmartModem non encore implemente\0" hayes ldx #msgh1 jsr outmsg ldx #msghay jmp outmsg ; Modem Manuel msg1 asc "C Connecte\0" msg2 asc "Attente de la porteuse\0" modemoff ldaa dr1 anda #$bf oraa #$80 staa dr1 ldx #msgh3 jmp outmsg validcd ldab counter addb #$22 ldaa #4 valid2 bita dr1 bne valid3 cmpb counter bcc valid2 bita dr1 valid3 rts testcd ldaa #4 bita dr1 beq test3 ldab counter addb #$19 test2 bita dr1 beq test3 cmpb counter bcc test2 bita dr1 test3 rts modemloop sei jsr eixin cli mloop1 jsr testcd bne endmloop ldaa #$2 bita aciacr beq mloop2 jsr intst beq mloop2 ldab sav2 bitb #$4 beq mloop11 jsr out mloop11 jsr xout mloop2 ldaa #$20 bita trcsr beq mloop1 jsr xintst beq mloop1 ldab sav2 bitb #8 beq mloop21 jsr xout mloop21 jsr out bra mloop1 endmloop sei jsr dixin cli rts modem lds #stkbase sei ldaa posxin staa rcvxin cli jsr setup ldx #msg2 jsr outmsg ldaa sav2 sei ldab dr1 andb #$c7 bita #1 beq modset1 orab #$8 modset1 bita #2 beq modset2 orab #$10 modset2 bita #4 beq modset3 andb #$7f modset3 orab #$40 stab dr1 cli waitcd jsr intst beq wait2 cmpa #abort beq remodem wait2 jsr validcd bne waitcd sei ldab dr1 andb #$7f stab dr1 cli ldab #$8 ldaa #'M' bitb dr1 bne modem5 ldaa #'B' modem5 jsr out ldx #msg1 jsr outmsg jsr modemloop remodem jsr modemoff jmp modem modem3 cmpa #$0d beq modem3 ; setup msgs1 asc "M)oniteur, T)est, E)cho, D)uplex, " asc "V)itesse, P)rotocole, C)onnection\0" msgs2 asc "Xon/Xoff \0" msgs3 asc "RTS/CTS \0" msgs5 asc " Test \0" msgs6 asc " Normal \0" msgs7 asc "Half \0" msgs8 asc "Full \0" msgs9 asc "Echo on \0" msgs10 asc "Echo off \0" pmsg ldaa 0,x beq pmsg2 jsr out inx bra pmsg pmsg2 rts modeline ldaa #$0C jsr out ldaa sav2 lsra eora sav2 ldx #$1200 bita #$1 beq modln2 ldx #$75 modln2 jsr prx ldaa #'/' jsr out ldx #$1200 ldaa sav2 bita #$1 bne modln3 ldx #$75 modln3 jsr prx ldx #msgs5 ldaa sav2 bita #$2 bne modln4 ldx #msgs6 modln4 jsr pmsg ldx #msgs7 ldaa sav2 bita #$4 bne modln5 ldx #msgs8 modln5 jsr pmsg ldx #msgs9 ldaa sav2 bita #$8 bne modln6 ldx #msgs10 modln6 jsr pmsg ldx #msgs2 ldaa sav2 bita #$40 bne modln7 jsr pmsg modln7 ldx #msgs3 ldaa sav2 bita #$20 beq modln8 jsr pmsg modln8 jsr outcr ldx #msgs1 jmp outmsg setup0 bitb #$2 beq setup1 andb #$F7 setup1 stab sav2 setup jsr modeline setupin jsr in jsr maj ldab sav2 cmpa #'M' bne setup2 jmp monloop setup2 cmpa #'T' bne setup3 eorb #2 bra setup0 setup3 cmpa #'D' bne setup4 eorb #4 bra setup0 setup4 cmpa #'E' bne setup5 eorb #8 bra setup0 setup5 cmpa #'P' bne setup6 addb #$20 bvc setup0 eorb #$80 bra setup0 setup6 cmpa #'V' bne setup7 andb #$f3 eorb #$1 bitb #$1 beq setup0 orab #$C bra setup0 setup7 cmpa #'C' beq setup8 cmpa #$0D bne setupin setup8 jmp outcr ; DASM mnemosav equ $9a formatsav equ $9b decode ldx #mycode abx ldaa 0,x cmpb #$8d beq decod2 cmpb #$60 bcs decod3 lsrb lsrb lsrb lsrb andb #$3 ldx #format tsta bpl decod4 orab #$4 decod4 abx anda #$7f beq decod5 ldab 0,x rts decod3 andb #$F0 cmpb #$20 beq decod2 decod5 ldab #$01 rts decod2 ldab #$72 rts dasmins ldx r2 ldab 0,x jsr decode staa mnemosav stab formatsav jsr prhexa jsr prmnemo jsr prargs ldab formatsav andb #$3 ldx r2 abx stx r2 jmp outcr prmnemo ldab mnemosav clra asld asld addd #mnemo std xsav ldx xsav ldab #$4 prmn2 pshb ldaa 0,x inx oraa #$20 jsr out pulb decb bne prmn2 out3bl ldab #$3 outnbl pshb jsr outsp pulb decb bne outnbl rts prhexa ldx r2 jsr prx jsr outt jsr outsp ldx r2 ldab 0,x jsr prb ldx r2 ldaa formatsav anda #$3 ldab #$a deca beq prhexa1 deca beq prhexa3 jsr outsp ldx 1,x jsr prx bra prhexa2 prhexa3 jsr out3bl ldab 1,x jsr prb prhexa2 ldab #$5 prhexa1 jmp outnbl prargs ldaa formatsav staa mnemosav cmpa #$72 beq relatif asl mnemosav bcc prargs2 ldaa #'#' jsr out prargs2 asl mnemosav bcc prargs3 ldaa #'$' jsr out prargs3 ldx r2 asl mnemosav bcc prargs4 ldab 1,x jsr prb prargs4 asl mnemosav bcc prargs5 ldx 1,x jsr prx prargs5 asl mnemosav bcc prargs6 ldaa #',' jsr out ldaa #'X' jsr out prargs6 rts relatif ldaa #'$' jsr out ldx r2 ldab 1,x clra tstb bpl relat2 coma relat2 addd r2 addd #$2 std xsav ldx xsav jmp prx ; MASM masmins jsr parse bcs masmerr clrb masmloop pshb jsr decode subd mnemosav beq masmfound pulb incb bne masmloop ldaa formatsav cmpa #$e2 bne ms2 ldaa #$d3 bra ms1 ms2 cmpa #$62 bne ms3 ldaa #$53 bra ms1 ms3 cmpa #$53 beq ms4 masmerr sec rts ms4 ldaa #$72 ms1 staa formatsav bra masmloop masmfound pulb ldx r2 stab 0,x ldaa formatsav cmpa #$72 beq masmrel anda #$3 cmpa #3 beq masmf2 cmpa #2 beq masmf1 clc rts masmrel ldd r1 subd #2 subd r2 tstb bpl masmrel2 coma masmrel2 tsta bne masmerr stab 1,x clc rts masmf1 ldab r1+1 stab 1,x clc rts masmf2 ldd r1 std 1,x clc rts nxtchar stx xsav ldx possav ldaa 0,x inx stx possav jsr maj ldx xsav rts parse ldaa #(mnemend-mnemo)>>2 staa mnemosav ldd possav std r1 parse2 dec mnemosav beq masmerr ldab mnemosav clra asld asld addd #mnemo std xsav ldx xsav ldaa 0,x beq masmerr ldd r1 std possav ldab #$4 parse1 ldaa 0,x cmpa #$20 beq parsed1 tstb beq parsed1 jsr nxtchar cmpa 0,x bne parse2 inx decb bra parse1 parsed1 clr formatsav parse3 jsr nxtchar cmpa #$20 beq parse3 cmpa #'#' bne parse4 ldaa #$80 oraa formatsav staa formatsav jsr nxtchar parse4 cmpa #'$' bne parse5 jsr nxtchar parse5 ldx possav dex jsr readhex ldab flag ldaa #$1 bitb #$6 beq parse6 ldaa #$62 bitb #$4 beq parse6 ldaa #$53 parse6 oraa formatsav staa formatsav dex ldaa 0,x cmpa #',' bne parse7 inx ldaa 0,x jsr maj cmpa #'X' bne parserr inx ldaa formatsav oraa #$0C staa formatsav parse7 ldaa 0,x inx cmpa #$20 beq parse7 tsta beq parseok cmpa #';' beq parseok parserr sec rts parseok clc rts ; Tables de DASM et MASM mnemo asc "??? " asc "STAA" asc "STAB" asc "STD " asc "STX " asc "STS " asc "LDAA" asc "LDAB" asc "LDD " asc "LDX " asc "LDS " asc "BITA" asc "BITB" asc "CMPA" asc "CMPB" asc "CPX " asc "ADDA" asc "ADDB" asc "ADDD" asc "SUBA" asc "SUBB" asc "SUBD" asc "ADCA" asc "ADCB" asc "SBCA" asc "SBCB" asc "EORA" asc "EORB" asc "ANDA" asc "ANDB" asc "ORAA" asc "ORAB" asc "ASR " asc "ASRA" asc "ASRB" asc "LSR " asc "LSRA" asc "LSRB" asc "LSRD" asc "ASL " asc "ASLA" asc "ASLB" asc "ASLD" asc "INC " asc "INCA" asc "INCB" asc "INS " asc "INX " asc "DEC " asc "DECA" asc "DECB" asc "DES " asc "DEX " asc "PSHA" asc "PSHB" asc "PSHX" asc "PULA" asc "PULB" asc "PULX" asc "SBA " asc "CBA " asc "ABA " asc "ABX " asc "MUL " asc "BRA " asc "BRN " asc "BHI " asc "BLS " asc "BCC " asc "BCS " asc "BNE " asc "BEQ " asc "BVC " asc "BVS " asc "BPL " asc "BMI " asc "BGE " asc "BLT " asc "BGT " asc "BLE " asc "BSR " asc "JSR " asc "JMP " asc "RTI " asc "WAIT" asc "SWI " asc "RTS " asc "TST " asc "TSTA" asc "TSTB" asc "ROL " asc "ROLA" asc "ROLB" asc "ROR " asc "RORA" asc "RORB" asc "TAB " asc "TBA " asc "TAP " asc "TPA " asc "TSX " asc "TXS " asc "DAA " asc "NEG " asc "NEGA" asc "NEGB" asc "COM " asc "COMA" asc "COMB" asc "CLR " asc "CLRA" asc "CLRB" asc "CLV " asc "SEV " asc "CLC " asc "SEC " asc "CLI " asc "SEI " asc "NOP " mnemend equ * mycode fcc $00,$76,$00,$00,$26,$2A,$62,$63 fcc $2F,$34,$70,$71,$72,$73,$74,$75 fcc $3B,$3C,$00,$00,$00,$00,$60,$61 fcc $00,$66,$00,$3D,$00,$00,$00,$00 fcc $40,$41,$42,$43,$44,$45,$46,$47 fcc $48,$49,$4A,$4B,$4C,$4D,$4E,$4F fcc $64,$2E,$38,$39,$33,$65,$35,$36 fcc $3A,$56,$3E,$53,$37,$3F,$54,$55 fcc $68,$00,$00,$6B,$24,$00,$5E,$21 fcc $28,$5B,$31,$00,$2C,$58,$00,$6E fcc $69,$00,$00,$6C,$25,$00,$5F,$22 fcc $29,$5C,$32,$00,$2D,$59,$00,$6F fcc $67,$00,$00,$6A,$23,$00,$5D,$20 fcc $27,$5A,$30,$00,$2B,$57,$52,$6D fcc $67,$00,$00,$6A,$23,$00,$5D,$20 fcc $27,$5A,$30,$00,$2B,$57,$52,$6D fcc $13,$0D,$18,$95,$1C,$0B,$06,$00 fcc $1A,$16,$1E,$10,$8F,$50,$8A,$00 fcc $13,$0D,$18,$15,$1C,$0B,$06,$01 fcc $1A,$16,$1E,$10,$0F,$51,$0A,$05 fcc $13,$0D,$18,$15,$1C,$0B,$06,$01 fcc $1A,$16,$1E,$10,$0F,$51,$0A,$05 fcc $13,$0D,$18,$15,$1C,$0B,$06,$01 fcc $1A,$16,$1E,$10,$0F,$51,$0A,$05 fcc $14,$0E,$19,$92,$1D,$0C,$07,$00 fcc $1B,$17,$1F,$11,$88,$00,$89,$00 fcc $14,$0E,$19,$12,$1D,$0C,$07,$02 fcc $1B,$17,$1F,$11,$08,$03,$09,$04 fcc $14,$0E,$19,$12,$1D,$0C,$07,$02 fcc $1B,$17,$1F,$11,$08,$03,$09,$04 fcc $14,$0E,$19,$12,$1D,$0C,$07,$02 fcc $1B,$17,$1F,$11,$08,$03,$09,$04 format fcc $E2,$62,$6E,$53,$D3 crasm-1.11/test/opcode.z80.asm000066400000000000000000000154731475737230500161420ustar00rootroot00000000000000;;; Author: Leon Bottou ;;; Public Domain. ; All Z80 opcodes cpu z80 *=4000H adr=12345 dd=23H n=45Q nn=23456 adc a,(hl) adc a,(ix+dd) adc a,(iy+dd) adc a,a adc a,b adc a,c adc a,d adc a,e adc a,h adc a,l adc a,n adc hl,bc adc hl,de adc hl,hl adc hl,sp add a,(hl) add a,(ix+dd) add a,(iy+dd) add a,a add a,b add a,c add a,d add a,e add a,h add a,l add a,n add hl,bc add hl,de add hl,hl add hl,sp add ix,bc add ix,de add ix,ix add ix,sp add iy,bc add iy,de add iy,iy add iy,sp and (hl) and (ix+dd) and (iy+dd) and a and b and c and d and e and h and l and n bit 0,(hl) bit 0,(ix+dd) bit 0,(iy+dd) bit 0,a bit 0,b bit 0,c bit 0,d bit 0,e bit 0,h bit 0,l bit 1,(hl) bit 1,(ix+dd) bit 1,(iy+dd) bit 1,a bit 1,b bit 1,c bit 1,d bit 1,e bit 1,h bit 1,l bit 2,(hl) bit 2,(ix+dd) bit 2,(iy+dd) bit 2,a bit 2,b bit 2,c bit 2,d bit 2,e bit 2,h bit 2,l bit 3,(hl) bit 3,(ix+dd) bit 3,(iy+dd) bit 3,a bit 3,b bit 3,c bit 3,d bit 3,e bit 3,h bit 3,l bit 4,(hl) bit 4,(ix+dd) bit 4,(iy+dd) bit 4,a bit 4,b bit 4,c bit 4,d bit 4,e bit 4,h bit 4,l bit 5,(hl) bit 5,(ix+dd) bit 5,(iy+dd) bit 5,a bit 5,b bit 5,c bit 5,d bit 5,e bit 5,h bit 5,l bit 6,(hl) bit 6,(ix+dd) bit 6,(iy+dd) bit 6,a bit 6,b bit 6,c bit 6,d bit 6,e bit 6,h bit 6,l bit 7,(hl) bit 7,(ix+dd) bit 7,(iy+dd) bit 7,a bit 7,b bit 7,c bit 7,d bit 7,e bit 7,h bit 7,l call adr call c,adr call m,adr call nc,adr call nz,adr call p,adr call pe,adr call po,adr call z,adr ccf cp (hl) cp (ix+dd) cp (iy+dd) cp a cp b cp c cp d cp e cp h cp l cp n cpd cpdr cpi cpir cpl daa dec (hl) dec (ix+dd) dec (iy+dd) dec a dec b dec bc dec c dec d dec de dec e dec h dec hl dec ix dec iy dec l dec sp di here1 djnz here1 ei ex (sp),hl ex (sp),ix ex (sp),iy ex af,af' ex de,hl exx halt im 0 im 1 im 2 in a,(c) in a,(n) in b,(c) in c,(c) in d,(c) in e,(c) in h,(c) in l,(c) inc (hl) inc (ix+dd) inc (iy+dd) inc a inc b inc bc inc c inc d inc de inc e inc h inc hl inc ix inc iy inc l inc sp ind indr ini inir jp (hl) jp (ix) jp (iy) jp adr jp c,adr jp m,adr jp nc,adr jp nz,adr jp p,adr jp pe,adr jp po,adr jp z,adr jr c,here2 here2 jr here2 jr nc,here2 jr nz,here2 jr z,here2 ld (bc),a ld (de),a ld (hl),a ld (hl),b ld (hl),c ld (hl),d ld (hl),e ld (hl),h ld (hl),l ld (hl),n ld (ix+dd),a ld (ix+dd),b ld (ix+dd),c ld (ix+dd),d ld (ix+dd),e ld (ix+dd),h ld (ix+dd),l ld (ix+dd),n ld (iy+dd),a ld (iy+dd),b ld (iy+dd),c ld (iy+dd),d ld (iy+dd),e ld (iy+dd),h ld (iy+dd),l ld (iy+dd),n ld (nn),a ld (nn),bc ld (nn),de ld (nn),hl ld (nn),ix ld (nn),iy ld (nn),sp ld a,(bc) ld a,(de) ld a,(hl) ld a,(ix+dd) ld a,(iy+dd) ld a,(nn) ld a,a ld a,b ld a,c ld a,d ld a,e ld a,h ld a,i ld a,l ld a,n ld a,r ld b,(hl) ld b,(ix+dd) ld b,(iy+dd) ld b,a ld b,b ld b,c ld b,d ld b,e ld b,h ld b,l ld b,n ld bc,(nn) ld bc,nn ld c,(hl) ld c,(ix+dd) ld c,(iy+dd) ld c,a ld c,b ld c,c ld c,d ld c,e ld c,h ld c,l ld c,n ld d,(hl) ld d,(ix+dd) ld d,(iy+dd) ld d,a ld d,b ld d,c ld d,d ld d,e ld d,h ld d,l ld d,n ld de,(nn) ld de,nn ld e,(hl) ld e,(ix+dd) ld e,(iy+dd) ld e,a ld e,b ld e,c ld e,d ld e,e ld e,h ld e,l ld e,n ld h,(hl) ld h,(ix+dd) ld h,(iy+dd) ld h,a ld h,b ld h,c ld h,d ld h,e ld h,h ld h,l ld h,n ld hl,(nn) ld hl,nn ld i,a ld ix,(nn) ld ix,nn ld iy,(nn) ld iy,nn ld l,(hl) ld l,(ix+dd) ld l,(iy+dd) ld l,a ld l,b ld l,c ld l,d ld l,e ld l,h ld l,l ld l,n ld r,a ld sp,(nn) ld sp,hl ld sp,ix ld sp,iy ld sp,nn ldd lddr ldi ldir neg nop or (hl) or (ix+dd) or (iy+dd) or a or b or c or d or e or h or l or n otdr otir out (c),a out (c),b out (c),c out (c),d out (c),e out (c),h out (c),l out (n),a outd outi pop af pop bc pop de pop hl pop ix pop iy push af push bc push de push hl push ix push iy res 0,(hl) res 0,(ix+dd) res 0,(iy+dd) res 0,a res 0,b res 0,c res 0,d res 0,e res 0,h res 0,l res 1,(hl) res 1,(ix+dd) res 1,(iy+dd) res 1,a res 1,b res 1,c res 1,d res 1,e res 1,h res 1,l res 2,(hl) res 2,(ix+dd) res 2,(iy+dd) res 2,a res 2,b res 2,c res 2,d res 2,e res 2,h res 2,l res 3,(hl) res 3,(ix+dd) res 3,(iy+dd) res 3,a res 3,b res 3,c res 3,d res 3,e res 3,h res 3,l res 4,(hl) res 4,(ix+dd) res 4,(iy+dd) res 4,a res 4,b res 4,c res 4,d res 4,e res 4,h res 4,l res 5,(hl) res 5,(ix+dd) res 5,(iy+dd) res 5,a res 5,b res 5,c res 5,d res 5,e res 5,h res 5,l res 6,(hl) res 6,(ix+dd) res 6,(iy+dd) res 6,a res 6,b res 6,c res 6,d res 6,e res 6,h res 6,l res 7,(hl) res 7,(ix+dd) res 7,(iy+dd) res 7,a res 7,b res 7,c res 7,d res 7,e res 7,h res 7,l ret ret c ret m ret nc ret nz ret p ret pe ret po ret z reti retn rl (hl) rl (ix+dd) rl (iy+dd) rl a rl b rl c rl d rl e rl h rl l rla rlc (hl) rlc (ix+dd) rlc (iy+dd) rlc a rlc b rlc c rlc d rlc e rlc h rlc l rlca rld rr (hl) rr (ix+dd) rr (iy+dd) rr a rr b rr c rr d rr e rr h rr l rra rrc (hl) rrc (ix+dd) rrc (iy+dd) rrc a rrc b rrc c rrc d rrc e rrc h rrc l rrca rrd rst 00H rst 08H rst 10H rst 18H rst 20H rst 28H rst 30H rst 38H sbc a,(hl) sbc a,(ix+dd) sbc a,(iy+dd) sbc a,a sbc a,b sbc a,c sbc a,d sbc a,e sbc a,h sbc a,l sbc a,n sbc hl,bc sbc hl,de sbc hl,hl sbc hl,sp scf set 0,(hl) set 0,(ix+dd) set 0,(iy+dd) set 0,a set 0,b set 0,c set 0,d set 0,e set 0,h set 0,l set 1,(hl) set 1,(ix+dd) set 1,(iy+dd) set 1,a set 1,b set 1,c set 1,d set 1,e set 1,h set 1,l set 2,(hl) set 2,(ix+dd) set 2,(iy+dd) set 2,a set 2,b set 2,c set 2,d set 2,e set 2,h set 2,l set 3,(hl) set 3,(ix+dd) set 3,(iy+dd) set 3,a set 3,b set 3,c set 3,d set 3,e set 3,h set 3,l set 4,(hl) set 4,(ix+dd) set 4,(iy+dd) set 4,a set 4,b set 4,c set 4,d set 4,e set 4,h set 4,l set 5,(hl) set 5,(ix+dd) set 5,(iy+dd) set 5,a set 5,b set 5,c set 5,d set 5,e set 5,h set 5,l set 6,(hl) set 6,(ix+dd) set 6,(iy+dd) set 6,a set 6,b set 6,c set 6,d set 6,e set 6,h set 6,l set 7,(hl) set 7,(ix+dd) set 7,(iy+dd) set 7,a set 7,b set 7,c set 7,d set 7,e set 7,h set 7,l sla (hl) sla (ix+dd) sla (iy+dd) sla a sla b sla c sla d sla e sla h sla l sra (hl) sra (ix+dd) sra (iy+dd) sra a sra b sra c sra d sra e sra h sra l srl (hl) srl (ix+dd) srl (iy+dd) srl a srl b srl c srl d srl e srl h srl l sub (hl) sub (ix+dd) sub (iy+dd) sub a sub b sub c sub d sub e sub h sub l sub n xor (hl) xor (ix+dd) xor (iy+dd) xor a xor b xor c xor d xor e xor h xor l xor n crasm-1.11/test/reference_output/000077500000000000000000000000001475737230500171135ustar00rootroot00000000000000crasm-1.11/test/reference_output/copy.6800.out000066400000000000000000000002571475737230500212160ustar00rootroot00000000000000S1138000CE4000DF40CE1430DF44CE6000DF42BDFE S113801080133EDE409F4035DE42D6459644DB4326 S11380209942D74397429C42270632A7000820F67C S10F8030309E40DF407F00447F00453953 S9030000FC crasm-1.11/test/reference_output/forth.6801.out000066400000000000000000000012611475737230500213630ustar00rootroot00000000000000S1131000DC80DE82ED000909DF8238DF80EE006ECD S113101000DE820808DF82EE000808DF80EE006E42 S113102000DE800808DF80EE006E003986666F728D S11310307468BD102B81200000008464757000006A S1131040383C3C7E10218564726F70103A387E10F3 S113105021866E64726F701046382705323209207B S1131060F97E1021857377617010513832333C3723 S1131070367E1021857069636B10643233049F845B S1131080D384DD84DE84EE003C7E1021856F76659A S11310907210743233383C37363C7E102184726FC0 S11310A074108C38DF843832333CDE843C37367E2F S11310B010218875736572766F63109DBD102B8146 S11310C02000001035C864757064726F701035BDEF S11310D010001040104D10114C594220466F72748C S10510E0682E74 S10510C110C554 S10D10E24C594220466F7274682EC8 S105103710B2F1 S9030000FC crasm-1.11/test/reference_output/math16.6502.out000066400000000000000000000013261475737230500213410ustar00rootroot00000000000000S1138000A5201865228520A5216523852160A90066 S11380108520852160242110FBA90038E5208520D6 S1138020A900E521852160A90038E5228522A9005F S1138030E523852360A52038E5228520A521E523B5 S11380408521602C468060A52145238527242310A3 S113805003202780201580A9808525A900852485F3 S11380602646214620900B48A526186522852668B9 S113807065236A66266625662490E6052608A524F7 S11380808520A525852228D0BA242130B62427109E S11380900320198060A5208524A5218526A90185B2 S11380A0200A852685278521A5220522F095062408 S11380B0262526262627A526C522A527E5239009B9 S11380C08527A526E5228526382620262190DF60EF S11380D0A521452348242310032027802015802030 S11380E095806810034C198060A52148242310034F S11380F0202780201580209580A5268520A527850A S10B8100226810034C19806091 S9030000FC crasm-1.11/test/reference_output/memcpy.6800.out000066400000000000000000000002101475737230500215230ustar00rootroot00000000000000S1131000000000000000F610012718FE1002A600E0 S113101008FF1002FE1004A70008FF10045A26EB74 S1111020F710017D100027057A100020DE393C S9030000FC crasm-1.11/test/reference_output/modem.6801.out000066400000000000000000000230201475737230500213370ustar00rootroot00000000000000S113FFF0F120F291F057F05BF16BF063F05FF09950 S113F0000A0D4D6F6E6974657572204C59422E005D S113F0104572726575720045727265757220646519 S113F02020436865636B73756D004F564552464CBB S113F0304F570A0D000A0D5357493A2053502020C8 S113F04020502020412042202058005339303330B2 S113F0503030304643003BDE806E00DE846E00DEDE S113F060866E00CEF035BDF21B30EE05BDF230BD2C S113F070F22830BDF230BDF228E600BDF238BDF210 S113F08028E602BDF238E601BDF238BDF228EE03EF S113F090BDF230BDF2047EF37C8E00FFCEF056DF6D S113F0A080DF84DF86DF824F9788978C978A978DDD S113F0B0978BB69FCE818727044FB79FCFB49FCD40 S113F0C0848097898A07B79FCE0F8611970186F8A7 S113F0D0970086809702860197038603B7BFFE8652 S113F0E009B7BFFE979F861A9711D6028606C501F7 S113F0F0270286059710860597080ECEDFB0086FA5 S113F100008CDFFF26F8C50227037EF7397EF376ED S113F110C680DA9F2004C67FD49FD79FF7BFFE39ED S113F120968D4C16908C847F272ECEDF00C47F3AB8 S113F130D78DD611D612E7008160261B0EF69FCF1D S113F140C54026058613BDF1F7F69FCFC5202707D6 S113F1500FD602CA20D7023B0FCEF02A9611852083 S113F16027FAA60027F197130820F1D68B5CC41F59 S113F17017908A841F27E1CE00A03AD78BB6BFFE32 S113F180B6BFFFA7003B8D0327FC39D68C17908DA3 S113F19040847F27F55CC47FDF8ECEDF003A810890 S113F1A0261BB69FCF854026058611BDF1F7B69F75 S113F1B0CF852027080F960284DF97020E0F7C006C S113F1C08CA600DE8E202B0E0FC602F5BFFE27F79D S113F1D0F6BFFEB7BFFF0E398D0327FC39D68A1759 S113F1E0908B841F27F65CC41FCE00A03A0FD78AE9 S113F1F0A6000EC6FF390F0EC620D51127F8D6116A S113F20097130E39B69FCF2B04860A8DEA860D20FC S113F210E686088DE28D11860820DCA60027E58DA0 S113F220D60820F7862D20CF862020CB863A20C70B S113F230DF8ED68E8D02D68F37DB9ED79E32364434 S113F2404444448D0132840F8A30813A25028B076D S113F25020A5BDF204F69FCE8620C187270286230F S113F260BDF1F7CE9FC0B69FCA2BFBE6078DC98DB3 S113F270B3E6088DC38DADC6198DBDE6098DB98D74 S113F280A7E6048DB38DA5E6028DAD8D9FE6002023 S113F290A77C00889608DE0986089588260A968940 S113F2A02B0C86019A03200486FE94039703DE82C6 S113F2B06E00865CBDF1F7BDF204B6DFB0BDF1F7B8 S113F2C0CEDFB1BDF186811D27E881092604A600A1 S113F2D027F18108260B8CDFB127DCBDF211092050 S113F2E0E2810A27DE810D26056F007EF2048CDFA1 S113F2F0FF24D0BDF1F7A7000820C881612506814D S113F3007A2202802039968984F89789A600812779 S113F31026247F0092A60197937C0089A602080800 S113F3207C0089D689C5702608C5062704DC92DDD1 S113F33090A6000820C5A600BDF2FBC604D5892608 S113F340DFBDF36724DA8607958926054F979297E0 S113F350937C00895858585886045879009379004A S113F360924A26F60820CF16C030C1112403C10AE0 S113F37039C007C11039CEF000BDF21B8E00FF86E4 S113F3802AB7DFB0BDF2B7FEDFB18C41542605BD0C S113F390F69420E8BDF39920E3CEDFB1DF96968999 S113F3A084809789DE96BDF306DF96CEF3CEA10066 S113F3B0270F6D00270508080820F3CEF0107EF211 S113F3C01BEE01D6891784809789AD0020D648F2B8 S113F3D05220F4583FF4E02EF44947F4B152F59C1E S113F3E057F5153AF49A58F7393EF4A92BF44D2DF4 S113F3F0F4514DF4C33CF4D159F4BF3DF5064CF53A S113F400F021F61500F4073232DE96098CDFB126BE S113F41047DC90CA0FDD929691840F260BDE90BDD7 S113F420F204BDF230BDF224BDF228DE90DF94E692 S113F43000BDF238BDF43F25DE39DE9408DF94DCEC S113F44090DE9008DF909392398610200686202063 S113F4500286409A899789391784889789C506272F S113F460F6C508260AC5202619C540261B20AEDE8F S113F470949693A700C5042705DC92ED000808DFE5 S113F4809439DC90D3922004DC909392DD90DD9249 S113F490DE90863DBDF1F77EF230CA08C48FD7896D S113F4A0C5062704DC90DD9439DE94BDF2307EF28B S113F4B02C867E978FFCDFAEFEDFACBD008F3FDE77 S113F4C0926E00DE90A600DE94A700BDF43A25F308 S113F4D039C5062704DC90DD94399691841F260BE8 S113F4E0DE90BDF204BDF230BDF224BDF228DE9000 S113F4F0DF94E60017C47FC1202402862EBDF1F7F5 S113F500BDF43F25D539C5102705DC92FDDFACDC01 S113F51090FDDFAE39DE90DC9293904D2604C10F4E S113F5202502C60F5CD7988653BDF1F78631BDF12D S113F530F77F009ED698CB03BDF238BDF230E600CB S113F54008BDF2387A009826F5D69E53BDF238BD30 S113F550F20D09DF90BDF43F25BBCEF04B7EF21BCC S113F5603232BDF3BBBDF186811D26F939BDF1866A S113F570BDF36725F839BDF186BDF36724E2585819 S113F5805858D799BDF186BDF36724D4DA99179BEF S113F5909E979E39BDF186BDF36725F8BDF186813E S113F5A00A27F9810D27F5815326B7BDF186BDF3EE S113F5B06724AF5D27DEC10927B37F009E8DB7C0E6 S113F5C003D79827CF8DAFD79A8DABD79BDE9A8D73 S113F5D0A59C9025069C922202E700087A009826B2 S113F5E0EE8D93D69E5327B4CEF017BDF21B20ACFC S113F5F0C5102613C5062704DC90DD94861436BD99 S113F600F94B324A26F839DC90DD94BDF94BDC9491 S113F610939225F739C5062704DC90DD94DE94BD6A S113F620F2308621B7DFB0BDF2BACEDFB008A60053 S113F630812027F9DF964D270FBDFA242505BDF952 S113F6404B20DABDF3BB20D57EF37C4552524F529A S113F650004E4F20434F4E4E454354004F4B000D38 S113F6600A454E44204F4620434F4E4E454354498D S113F6704F4E00536D6172744D6F64656D206E6FF3 S113F6806E20656E636F726520696D706C656D6563 S113F6906E746500CEF64BBDF21BCEF6737EF21B84 S113F6A04320436F6E6E6563746500417474656EC8 S113F6B07465206465206C6120706F727465757365 S113F6C06500960284BF8A809702CEF65C7EF21BA8 S113F6D0D688CB22860495022606D18824F8950282 S113F6E03986049502270ED688CB1995022706D1B0 S113F6F08824F89502390FBDF1100EBDF6E12633CA S113F7008602B5BFFE2712BDF18B270DF69FCFC52C S113F710042703BDF1F7BDF1C88620951127DCBD90 S113F720F1DD27D7F69FCFC5082703BDF1C8BDF18A S113F730F720C80FBDF1160E398E00FF0F968A9779 S113F7408B0EBDF8C9CEF6ABBDF21BB69FCF0FD65C S113F75002C4C785012702CA0885022702CA108588 S113F760042702C47FCA40D7020EBDF18B2704814F S113F7701D2723BDF6D026F20FD602C47FD7020E72 S113F780C608864DD50226028642BDF1F7CEF6A004 S113F790BDF21BBDF6F6BDF6C27EF739810D27FC1E S113F7A04D296F6E69746575722C205429657374C4 S113F7B02C20452963686F2C20442975706C65786A S113F7C02C2056296974657373652C205029726F37 S113F7D0746F636F6C652C2043296F6E6E65637460 S113F7E0696F6E00586F6E2F586F66662020005246 S113F7F054532F4354532020200020205465737405 S113F800202020200020204E6F726D616C2020008B S113F81048616C6620200046756C6C2020004563AE S113F820686F206F6E202020004563686F206F662C S113F83066202000A6002706BDF1F70820F63986C9 S113F8400CBDF1F7B69FCF44B89FCFCE120085010F S113F8502703CE0075BDF230862FBDF1F7CE12001E S113F860B69FCF85012603CE0075BDF230CEF7FAE0 S113F870B69FCF85022603CEF805BDF834CEF81026 S113F880B69FCF85042603CEF817BDF834CEF81EF4 S113F890B69FCF85082603CEF829BDF834CEF7E409 S113F8A0B69FCF85402603BDF834CEF7EFB69FCF81 S113F8B085202703BDF834BDF204CEF7A07EF21BE9 S113F8C0C5022702C4F7F79FCFBDF83FBDF186BD3F S113F8D0F2FBF69FCF814D26037EF37681542604F6 S113F8E0C80220DC81442604C80420D481452604AF S113F8F0C80820CC81502608CB2028C4C88020C04A S113F9008156260CC4F3C801C50127B4CA0C20B023 S113F91081432704810D26B47EF204CEFD0D3AA660 S113F92000C18D2723C160251654545454C403CEFA S113F930FE0D4D2A02CA043A847F2709E60039C421 S113F940F0C1202703C60139C67239DE94E600BD32 S113F950F91B979AD79BBDF991BDF96BBDF9C8D630 S113F9609BC403DE943ADF947EF204D69A4F0505D5 S113F970C3FB31DD8EDE8EC60437A600088A20BDA7 S113F980F1F7335A26F3C60337BDF228335A26F863 S113F99039DE94BDF230BDF224BDF228DE94E600D7 S113F9A0BDF238DE94969B8403C60A4A27174A2779 S113F9B00ABDF228EE01BDF2302008BDF986E60149 S113F9C0BDF238C6057EF988969B979A8172273ACC S113F9D078009A24058623BDF1F778009A240586D9 S113F9E024BDF1F7DE9478009A2405E601BDF238CF S113F9F078009A2405EE01BDF23078009A240A8634 S113FA002CBDF1F78658BDF1F7398624BDF1F7DE38 S113FA1094E6014F5D2A0143D394C30002DD8EDED8 S113FA208E7EF230BDFA9825235F37BDF91B939A79 S113FA302722335C26F4969B81E2260486D3201089 S113FA408162260486532008815327020D39867269 S113FA50979B20D633DE94E700969B8172270C8413 S113FA60038103271E810227140C39DC92830002D0 S113FA7093945D2A01434D26D3E7010C39D693E7CD S113FA80010C39DC92ED010C39DF8EDE96A60008FC S113FA90DF96BDF2FBDE8E398677979ADC96DD928F S113FAA07A009A27A7D69A4F0505C3FB31DD8EDE6F S113FAB08EA6002797DC92DD96C604A60081202737 S113FAC00E5D270BBDFA89A10026D5085A20EC7FCC S113FAD0009BBDFA89812027F98123260986809A13 S113FAE09B979BBDFA8981242603BDFA89DE96097A S113FAF0BDF306D6898601C50627088662C5042794 S113FB000286539A9B979B09A600812C261108A66E S113FB1000BDF2FB8158261508969B8A0C979BA67C S113FB200008812027F94D2706813B27020D390C57 S113FB30393F3F3F2053544141535441425354446D S113FB402053545820535453204C4441414C444175 S113FB50424C4444204C4458204C44532042495481 S113FB604142495442434D5041434D504243505801 S113FB702041444441414444424144444453554255 S113FB804153554242535542444144434141444305 S113FB90425342434153424342454F5241454F52DF S113FBA042414E4441414E44424F5241414F5241E1 S113FBB0424153522041535241415352424C5352B9 S113FBC0204C5352414C5352424C53524441534C97 S113FBD02041534C4141534C4241534C44494E43C0 S113FBE020494E4341494E4342494E5320494E58C1 S113FBF020444543204445434144454342444553FE S113FC00204445582050534841505348425053488B S113FC105850554C4150554C4250554C5853424104 S113FC20204342412041424120414258204D554CFD S113FC30204252412042524E2042484920424C53D5 S113FC40204243432042435320424E4520424551E3 S113FC5020425643204256532042504C20424D49A4 S113FC602042474520424C542042475420424C45B0 S113FC7020425352204A5352204A4D502052544954 S113FC8020574149545357492052545320545354F4 S113FC90205453544154535442524F4C20524F4CCD S113FCA041524F4C42524F5220524F5241524F52A6 S113FCB04254414220544241205441502054504126 S113FCC0205453582054585320444141204E454712 S113FCD0204E4547414E454742434F4D20434F4DEB S113FCE041434F4D42434C5220434C5241434C52AA S113FCF042434C562053455620434C4320534543DE S113FD0020434C4920534549204E4F502000760053 S113FD1000262A62632F347071727374753B3C0041 S113FD2000000060610066003D00000000404142A8 S113FD30434445464748494A4B4C4D4E4F642E3840 S113FD4039336535363A563E53373F5455680000CB S113FD506B24005E21285B31002C58006E69000082 S113FD606C25005F22295C32002D59006F6700006A S113FD706A23005D20275A30002B57526D6700001C S113FD806A23005D20275A30002B57526D130D183B S113FD90951C0B06001A161E108F508A00130D189E S113FDA0151C0B06011A161E100F510A05130D1807 S113FDB0151C0B06011A161E100F510A05130D18F7 S113FDC0151C0B06011A161E100F510A05140E19E4 S113FDD0921D0C07001B171F1188008900140E19AF S113FDE0121D0C07021B171F1108030904140E1916 S113FDF0121D0C07021B171F1108030904140E1906 S113FE00121D0C07021B171F1108030904E2626E7E S105FE1053D3C6 S9030000FC crasm-1.11/test/reference_output/opcode.z80.out000066400000000000000000000075101475737230500215400ustar00rootroot00000000000000:104000008EDD8E23FD8E238F88898A8B8C8DCE2525 :10401000ED4AED5AED6AED7A86DD8623FD8623872B :10402000808182838485C62509192939DD09DD1936 :10403000DD29DD39FD09FD19FD29FD39A6DDA623A0 :10404000FDA623A7A0A1A2A3A4A5E625CB46DDCB70 :104050002346FDCB2346CB47CB40CB41CB42CB4382 :10406000CB44CB45CB4EDDCB234EFDCB234ECB4FAC :10407000CB48CB49CB4ACB4BCB4CCB4DCB56DDCBF6 :104080002356FDCB2356CB57CB50CB51CB52CB53E2 :10409000CB54CB55CB5EDDCB235EFDCB235ECB5F1C :1040A000CB58CB59CB5ACB5BCB5CCB5DCB66DDCB56 :1040B0002366FDCB2366CB67CB60CB61CB62CB6342 :1040C000CB64CB65CB6EDDCB236EFDCB236ECB6F8C :1040D000CB68CB69CB6ACB6BCB6CCB6DCB76DDCBB6 :1040E0002376FDCB2376CB77CB70CB71CB72CB73A2 :1040F000CB74CB75CB7EDDCB237EFDCB237ECB7FFC :10410000CB78CB79CB7ACB7BCB7CCB7DCD3930DCFC :104110003930FC3930D43930C43930F43930EC39E5 :1041200030E43930CC39303FBEDDBE23FDBE23BF85 :10413000B8B9BABBBCBDFE25EDA9ED89EDA1EDB1C5 :104140002F2735DD3523FD35233D050B0D151B1DB3 :10415000252BDD2BFD2B2D3BF310FEFBE3DDE3FDDB :10416000E308EBD976ED46ED56ED5EED78DB25ED17 :1041700040ED48ED50ED58ED60ED6834DD3423FD41 :1041800034233C04030C14131C2423DD23FD232CB3 :1041900033EDAAEDBAEDA2EDB2E9DDE9FDE9C339EF :1041A00030DA3930FA3930D23930C23930F2393078 :1041B000EA3930E23930CA3930380018FE30FC2094 :1041C000FA28F80212777071727374753625DD77EC :1041D00023DD7023DD7123DD7223DD7323DD742382 :1041E000DD7523DD362325FD7723FD7023FD712347 :1041F000FD7223FD7323FD7423FD7523FD362325F6 :1042000032A05BED43A05BED53A05B22A05BDD22FF :10421000A05BFD22A05BED73A05B0A1A7EDD7E230E :10422000FD7E233AA05B7F78797A7B7CED577D3EDB :1042300025ED5F46DD4623FD46234740414243448A :10424000450625ED4BA05B01A05B4EDD4E23FD4EE8 :10425000234F48494A4B4C4D0E2556DD5623FD56FB :1042600023575051525354551625ED5BA05B11A0B6 :104270005B5EDD5E23FD5E235F58595A5B5C5D1E0D :104280002566DD6623FD66236760616263646526DB :10429000252AA05B21A05BED47DD2AA05BDD21A0E4 :1042A0005BFD2AA05BFD21A05B6EDD6E23FD6E230E :1042B0006F68696A6B6C6D2E25ED4FED7BA05BF925 :1042C000DDF9FDF931A05BEDA8EDB8EDA0EDB0EDA5 :1042D0004400B6DDB623FDB623B7B0B1B2B3B4B572 :1042E000F625EDBBEDB3ED79ED41ED49ED51ED591D :1042F000ED61ED69D325EDABEDA3F1C1D1E1DDE1D8 :10430000FDE1F5C5D5E5DDE5FDE5CB86DDCB238615 :10431000FDCB2386CB87CB80CB81CB82CB83CB8459 :10432000CB85CB8EDDCB238EFDCB238ECB8FCB8865 :10433000CB89CB8ACB8BCB8CCB8DCB96DDCB23960D :10434000FDCB2396CB97CB90CB91CB92CB93CB94B9 :10435000CB95CB9EDDCB239EFDCB239ECB9FCB98D5 :10436000CB99CB9ACB9BCB9CCB9DCBA6DDCB23A66D :10437000FDCB23A6CBA7CBA0CBA1CBA2CBA3CBA419 :10438000CBA5CBAEDDCB23AEFDCB23AECBAFCBA845 :10439000CBA9CBAACBABCBACCBADCBB6DDCB23B6CD :1043A000FDCB23B6CBB7CBB0CBB1CBB2CBB3CBB479 :1043B000CBB5CBBEDDCB23BEFDCB23BECBBFCBB8B5 :1043C000CBB9CBBACBBBCBBCCBBDC9D8F8D0C0F036 :1043D000E8E0C8ED4DED45CB16DDCB2316FDCB2334 :1043E00016CB17CB10CB11CB12CB13CB14CB15178D :1043F000CB06DDCB2306FDCB2306CB07CB00CB01C1 :10440000CB02CB03CB04CB0507ED6FCB1EDDCB235B :104410001EFDCB231ECB1FCB18CB19CB1ACB1BCB2E :104420001CCB1D1FCB0EDDCB230EFDCB230ECB0FE4 :10443000CB08CB09CB0ACB0BCB0CCB0D0FED67C751 :10444000CFD7DFE7EFF7FF9EDD9E23FD9E239F98EA :10445000999A9B9C9DDE25ED42ED52ED62ED7237FF :10446000CBC6DDCB23C6FDCB23C6CBC7CBC0CBC1D0 :10447000CBC2CBC3CBC4CBC5CBCEDDCB23CEFDCB08 :1044800023CECBCFCBC8CBC9CBCACBCBCBCCCBCD20 :10449000CBD6DDCB23D6FDCB23D6CBD7CBD0CBD140 :1044A000CBD2CBD3CBD4CBD5CBDEDDCB23DEFDCB78 :1044B00023DECBDFCBD8CBD9CBDACBDBCBDCCBDD70 :1044C000CBE6DDCB23E6FDCB23E6CBE7CBE0CBE1B0 :1044D000CBE2CBE3CBE4CBE5CBEEDDCB23EEFDCBE8 :1044E00023EECBEFCBE8CBE9CBEACBEBCBECCBEDC0 :1044F000CBF6DDCB23F6FDCB23F6CBF7CBF0CBF120 :10450000CBF2CBF3CBF4CBF5CBFEDDCB23FEFDCB57 :1045100023FECBFFCBF8CBF9CBFACBFBCBFCCBFD0F :10452000CB26DDCB2326FDCB2326CB27CB20CB21CF :10453000CB22CB23CB24CB25CB2EDDCB232EFDCB07 :10454000232ECB2FCB28CB29CB2ACB2BCB2CCB2D5F :10455000CB3EDDCB233EFDCB233ECB3FCB38CB390F :10456000CB3ACB3BCB3CCB3D96DD9623FD962397B8 :10457000909192939495D625AEDDAE23FDAE23AFF8 :08458000A8A9AAABACADEE2521 :00000001FF crasm-1.11/test/reference_output/stdnames.6801.out000066400000000000000000000000131475737230500220510ustar00rootroot00000000000000S9030000FC crasm-1.11/test/reference_output/tstif.crasm.out000066400000000000000000000000661475737230500221030ustar00rootroot00000000000000S11320001FFC400000AD0FA003E80FA013880FA031 S9030000FC crasm-1.11/test/reference_output/tstinclude.crasm.out000066400000000000000000000012451475737230500231300ustar00rootroot00000000000000S1133000AD001000040003000200010000300B308A S1133010093007300530036573706F69720001650C S11330206E636F726500040003000200010000304B S11330302D302B30293027302500020000100000ED S1133040002000000003030303030303030303033B S1133050030303030303030303030303030303033C S1133060030303030303030303030303030303032C S1133070030303030303030303030303030303031C S1133080030303030303030303030303030303030C S113309003030303030303030303030303030303FC S11330A00303030303030303036A65206D27696EA7 S11330B07465726573736520656E636F72652061F4 S11330C0752063616C63756C2065742061206C27C6 S11330D061666669636861676520646573207472FC S10830E06565732E007C S11320001FFC400000AD0FA003E80FA013880FA031 S9030000FC crasm-1.11/test/reference_output/tstmacros.crasm.out000066400000000000000000000011721475737230500227700ustar00rootroot00000000000000S1133000AD001000040003000200010000300B308A S1133010093007300530036573706F69720001650C S11330206E636F726500040003000200010000304B S11330302D302B30293027302500020000100000ED S1133040002000000003030303030303030303033B S1133050030303030303030303030303030303033C S1133060030303030303030303030303030303032C S1133070030303030303030303030303030303031C S1133080030303030303030303030303030303030C S113309003030303030303030303030303030303FC S11330A00303030303030303036A65206D27696EA7 S11330B07465726573736520656E636F72652061F4 S11330C0752063616C63756C2065742061206C27C6 S11330D061666669636861676520646573207472FC S10830E06565732E007C S9030000FC crasm-1.11/test/reference_output/uchess2.65C02.out000066400000000000000000000073421475737230500217240ustar00rootroot00000000000000S1131000A90085B7205414D8A2FF9AA2C886B2209A S11310107813204914C943D012A21FBD80159550DE S1131020CA10F8A21B86DCA9CCD019C945D00E2061 S1131030C11138A901E5B785B7A9EED007C940D0D9 S11310400B20B51285FB85FA85F9D0BBC90DD006F6 S1131050205B124CFD10C941F0034CF6104C00FF0C S1131060A6B5305CA5B0F008E008D004C5E6F02EC3 S1131070F6E3C901D002F6E3501EA00FA5B1D96072 S113108000F0038810F8B9B115D5E4900494E695FE S1131090E4180875E595E528E004F003303160A50F S11310A0E885DDA90085B5205B1220C111200F1150 S11310B020C111A90885B52018112041124C121322 S11310C0E0F9D00BA560C5B1D004A90085B4605087 S11310D0FDA007A5B1D96000F00588F0F110F6B9BC S11310E0B115D5E2900295E2C6B5A9FBC5B5F003EA S11310F0203512E6B560C908B012200213A21FB54C S113110050C5FAF003CA10F786FB86B04C0710A24C S113111010A90095DECA10FBA91085B0C6B0100155 S113112060202E12A4B0A20886B6C0081041C006E2 S1131130102EC004101FC001F009100E209D11D004 S1131140FBF0D920AB11D0FBF0D2A20486B620ABC1 S113115011D0FBF0C720AB11A5B6C904D0F7F0BC81 S1131160A21086B6209D11A5B6C908D0F7F0ADA28D S11311700686B620D91150053003206010202E12A7 S1131180C6B6A5B6C905F0EB20D911708F308D20F5 S11311906010A5B129F0C920F0EE4C1C1120D91122 S11311A03003206010202E12C6B66020D9119002A0 S11311B050F93007082060102850F0202E12C6B6CF S11311C060A20F38B460A977F5509560945038A99F S11311D077F5509550CA10EB60A5B1A6B6187DA05E S11311E01585B12988D042A5B1A220CA300ED550A8 S11311F0D0F9E0103033A97F69017001B8A5B5308A S113120024C90810204808A9F985B585B4205B12C3 S113121020C111201811203E12286885B5A5B430CC S11312200438A9FF6018A90060A9FF18B860A6B027 S1131230B55085B160205B1220C11120181120C166 S113124011BA86B3A6B29A6885B66885B0AA6895BD S11312505068AA6885B195504C8012BA86B3A6B27C S11312609AA5B148A8A21FD550F003CA10F9A9CC79 S113127095508A48A6B0B5509450488A48A5B648B7 S1131280BA86B2A6B39A60A6E4ECB115D004A9005C S1131290F00AA6E3D006A6EED002A9FFA20486B502 S11312A0C5FA900CF00A85FAA5B085FBA5B185F9BD S11312B0A92E4C6A14A6DC301CA5F9DDC115D01189 S11312C0CABDC11585FBCABDC11585F9CA86DCD066 S11312D01CA9FF85DCA20C86B586FAA21420111184 S11312E0A20486B5200F11A6FAE00F9012A6FBB552 S11312F05085FA86B0A5F985B1205B124C0710A978 S1131300FF60A20406F926FACAD0F905F985F98521 S1131310B16018A98065EB65EC65ED65E165DF38C2 S1131320E5F0E5F1E5E2E5E0E5DEE5EFE5E3B00271 S1131330A9004A18694065EC65ED38E5E44A186986 S11313409065DD65DD65DD65DD65E138E5E4E5E4F1 S1131350E5E5E5E5E5E0A6B1E033F016E034F012AA S1131360E022F00EE025F00AA6B0F009B450C01057 S113137010031869024C8712201714203B142022F2 S113138014A00020E913A97C206A14A21F98D55048 S1131390F040CA10F898290185FC984A4A4A4A291B S11313A0011865FC2901F003A92A2CA920206A143C S11313B0206A14C8982908F0CDA97C206A14203426 S11313C01420171420E91318986908A8C080F02B7A S11313D0D0B4A5B7F005BDE414D003BDD414206A7D S11313E014BD0415206A14D0CA8A48A219A92D2054 S11313F06A14CAD0FA68AA20171460202214A5FB24 S1131400207714A920206A14A5FA207714A9202093 S11314106A14A5F9207714A90D206A14A90A206A70 S11314201460A200A920206A148A207714E8E00836 S1131430D0F2F0E398297020771460A200BD9B14C9 S1131440F006206A14E8D0F560A93F206A14205FF2 S113145014294F60A91F8D737FA90B8D727F60AD16 S1131460717F2908F0F9AD707F6048AD717F291054 S1131470F0F9688D707F60484A4A4A4A20801468AF S1131480290F5AA8B98B147A4C6A14303132333488 S113149035363738394142434445464D6963726FA6 S11314A043686573732028632920313939362D3216 S11314B0303035205065746572204A656E6E696EF1 S11314C067732C207777772E62656E6C6F2E636F4F S11314D06D0D0A0057575757575757575757575770 S11314E05757575742424242424242424242424284 S11314F042424242575757575757575757575757CC S1131500575757574B51525242424E4E50505050DB S1131510505050504B51525242424E4E50505050E7 S1081520505050500082 S1131580030400070205010610171116121514139F S1131590737470777275717660676166626564638F S11315A000F0FF0110110FEFF1DFE1EEF2120E1F58 S11315B0210B0A06060404040402020202020202C7 S11315C00299250B25010033250736340D34340EDA S11015D052250D45350455220643330FCC3A S9030000FC crasm-1.11/test/stdnames.6801.asm000066400000000000000000000026651475737230500164630ustar00rootroot00000000000000;;; Author: Leon Bottou ;;; Public Domain. ; Names for builin 6801 registers ; Bit testing macros dummy vectors = $fff0 * = vectors vector.sci dw 0 vector.tof dw 0 vector.ocf dw 0 vector.icf dw 0 vector.irq dw 0 vector.swi dw 0 vector.nmi dw 0 vector.reset dw 0 * = $0 ddr1 db 0 ddr2 db 0 dr1 db 0 dr2 db 0 ddr3 db 0 ddr4 db 0 dr3 db 0 dr4 db 0 tcsr db 0 counter dw 0 ocr dw 0 icr dw 0 p3csr db 0 rmcr db 0 trcsr db 0 rdr db 0 tdr db 0 ramcr db 0 p3csr.is3 = p3csr{7} p3csr.eis3i = p3csr{6} p3csr.os3 = p3csr{4} p3csr.le = p3csr{3} ramcr.stby = ramcr{7} ramcr.rami = ramcr{6} tcsr.icf = tcsr{7} tcsr.ocf = tcsr{6} tcsr.tof = tcsr{5} tcsr.eici = tcsr{4} tcsr.eoci = tcsr{3} tcsr.etoi = tcsr{2} tcsr.iedg = tcsr{1} tcsr.olvl = tcsr{0} rmcr.cc1 = rmcr{3} rmcr.cc0 = rmcr{2} rmcr.ss1 = rmcr{1} rmcr.ss0 = rmcr{0} trcsr.rdrf = trcsr{7} trcsr.orfe = trcsr{6} trcsr.tdre = trcsr{5} trcsr.rie = trcsr{4} trcsr.re = trcsr{3} trcsr.tie = trcsr{2} trcsr.te = trcsr{1} trcsr.wu = trcsr{0} ;; bset BITSPEC --- ;; Sets bit BITSPEC ;; Clobbers A. bset macro ldaa #1<< BIT(\1) oraa ADDR(\1) staa ADDR(\1) endm ;; bclr BITSPEC --- ;; Clears bit BITSPEC ;; Clobbers A. bclr macro ldaa # $ff ^ (1<< BIT(\1)) bnomask \1 anda ADDR(\1) staa ADDR(\1) endm ;; btst BITSPEC --- ;; Clears bit BITSPEC ;; Set/Reset Z bit. ;; Clobbers A. btst macro ldaa #1<< BIT(\1) bmask \1 anda ADDR(\1) endm codecrasm-1.11/test/tstif.crasm.asm000066400000000000000000000005661475737230500165030ustar00rootroot00000000000000;;; Author: Leon Bottou ;;; Public Domain. * equ $2000 dw end1-4*2 end2 dw (end1-4)*2 end1 dw $ad if 1<2 if 1>2 dl 3000 else dw 4000 endc dw 1000 else if 1<>1 dw 6000/2 endc dw 2000 endc clist off if 1>2 dw 3000 else dw 4000 endc if 1<=1 dw 5000 if 1>2 dw 3000 else dw 4000 endc endc crasm-1.11/test/tstinclude.crasm.asm000066400000000000000000000001671475737230500175250ustar00rootroot00000000000000;;; Author: Leon Bottou ;;; Public Domain. ilist on include tstmacros.crasm.asm ilist off include tstif.crasm.asm crasm-1.11/test/tstmacros.crasm.asm000066400000000000000000000011241475737230500173600ustar00rootroot00000000000000;;; Author: Leon Bottou ;;; Public Domain. nam essai macro page 0,132 depart = $1000 fin = $2000 fcb = db lda macro fcb $ad ddb \1 endm ref macro .L dw \1 if \1>0 ref \1-1 endc dw .L endm final macro dw \# if \#>=2 dl \1,\2 exitm endc asc "encore" endm page * = depart+fin mlist on start lda depart ref 4 asc "espoir" final depart mlist off ref 4 end final depart,fin ds 2 ds 100,3 enfin asc "je m'interesse encore au calcul" asc " et a l'affichage des trees.\0" crasm-1.11/test/uchess2.65C02.asm000066400000000000000000000522601475737230500163160ustar00rootroot00000000000000;*********************************************************************** ; ; Kim-1 MicroChess (c) 1976-2005 Peter Jennings, www.benlo.com ; ;*********************************************************************** ; All rights reserved. ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions ; are met: ; 1. Redistributions of source code must retain the above copyright ; notice, this list of conditions and the following disclaimer. ; 2. Redistributions in binary form must reproduce the above copyright ; notice, this list of conditions and the following disclaimer in the ; documentation and/or other materials provided with the distribution. ; 3. The name of the author may not be used to endorse or promote products ; derived from this software without specific prior written permission. ; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR ; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ; ; modified by Daryl Rictor to work over a ; serial terminal connection, August 2002. ; ; Updated with corrections to earlier OCR errors by Bill Forster, August 2005. ; cpu 65c02 page 0,132 ; ; 6551 I/O Port Addresses ; ACIADat = $7F70 ACIASta = $7F71 ACIACmd = $7F72 ACIACtl = $7F73 ; ; page zero variables ; BOARD = $50 BK = $60 PIECE = $B0 SQUARE = $B1 SP2 = $B2 SP1 = $B3 INCHEK = $B4 STATE = $B5 MOVEN = $B6 REV = $B7 OMOVE = $DC WCAP0 = $DD COUNT = $DE BCAP2 = $DE WCAP2 = $DF BCAP1 = $E0 WCAP1 = $E1 BCAP0 = $E2 MOB = $E3 MAXC = $E4 CC = $E5 PCAP = $E6 BMOB = $E3 BMAXC = $E4 BMCC = $E5 ; was BCC (TASS doesn't like it as a label) BMAXP = $E6 XMAXC = $E8 WMOB = $EB WMAXC = $EC WCC = $ED WMAXP = $EE PMOB = $EF PMAXC = $F0 PCC = $F1 PCP = $F2 OLDKY = $F3 BESTP = $FB BESTV = $FA BESTM = $F9 DIS1 = $FB DIS2 = $FA DIS3 = $F9 temp = $FC ; ; ; *=$1000 ; load into RAM @ $1000-$15FF LDA #$00 ; REVERSE TOGGLE STA REV JSR Init_6551 CHESS CLD ; INITIALIZE LDX #$FF ; TWO STACKS TXS LDX #$C8 STX SP2 ; ; ROUTINES TO LIGHT LED ; DISPLAY AND GET KEY ; FROM KEYBOARD ; OUT JSR pout ; DISPLAY AND JSR KIN ; GET INPUT *** my routine waits for a keypress ; CMP OLDKY ; KEY IN ACC *** no need to debounce ; BEQ OUT ; (DEBOUNCE) ; STA OLDKY ; CMP #$43 ; [C] BNE NOSET ; SET UP LDX #$1F ; BOARD WHSET LDA SETW,X ; FROM STA BOARD,X ; SETW DEX BPL WHSET LDX #$1B ; *ADDED STX OMOVE ; INITS TO $FF LDA #$CC ; Display CCC BNE CLDSP ; NOSET CMP #$45 ; [E] BNE NOREV ; REVERSE JSR REVERSE ; BOARD IS SEC LDA #$01 SBC REV STA REV ; TOGGLE REV FLAG LDA #$EE ; IS BNE CLDSP ; NOREV CMP #$40 ; [P] BNE NOGO ; PLAY CHESS JSR GO CLDSP STA DIS1 ; DISPLAY STA DIS2 ; ACROSS STA DIS3 ; DISPLAY BNE CHESS ; NOGO CMP #$0D ; [Enter] BNE NOMV ; MOVE MAN JSR MOVE ; AS ENTERED JMP DISP NOMV CMP #$41 ; [Q] ***Added to allow game exit*** BEQ DONE ; quit the game, exit back to system. JMP INPUT ; process move DONE JMP $FF00 ; *** MUST set this to YOUR OS starting address ; ; THE ROUTINE JANUS DIRECTS THE ; ANALYSIS BY DETERMINING WHAT ; SHOULD OCCUR AFTER EACH MOVE ; GENERATED BY GNM ; ; ; JANUS LDX STATE BMI NOCOUNT ; ; THIS ROUTINE COUNTS OCCURRENCES ; IT DEPENDS UPON STATE TO INDEX ; THE CORRECT COUNTERS ; COUNTS LDA PIECE BEQ OVER ; IF STATE=8 CPX #$08 ; DO NOT COUNT BNE OVER ; BLK MAX CAP CMP BMAXP ; MOVES FOR BEQ XRT ; WHITE ; OVER INC MOB,X ; MOBILITY CMP #$01 ; + QUEEN BNE NOQ ; FOR TWO INC MOB,X ; NOQ BVC NOCAP LDY #$0F ; CALCULATE LDA SQUARE ; POINTS ELOOP CMP BK,Y ; CAPTURED BEQ FOUN ; BY THIS DEY ; MOVE BPL ELOOP FOUN LDA POINTS,Y CMP MAXC,X BCC LESS ; SAVE IF STY PCAP,X ; BEST THIS STA MAXC,X ; STATE ; LESS CLC PHP ; ADD TO ADC CC,X ; CAPTURE STA CC,X ; COUNTS PLP ; NOCAP CPX #$04 BEQ ON4 BMI TREE ;(=00 ONLY) XRT RTS ; ; GENERATE FURTHER MOVES FOR COUNT ; AND ANALYSIS ; ON4 LDA XMAXC ; SAVE ACTUAL STA WCAP0 ; CAPTURE LDA #$00 ; STATE=0 STA STATE JSR MOVE ; GENERATE JSR REVERSE ; IMMEDIATE JSR GNMZ ; REPLY MOVES JSR REVERSE ; LDA #$08 ; STATE=8 STA STATE ; GENERATE JSR GNM ; CONTINUATION JSR UMOVE ; MOVES ; JMP STRATGY ; FINAL EVALUATION NOCOUNT CPX #$F9 BNE TREE ; ; DETERMINE IF THE KING CAN BE ; TAKEN, USED BY CHKCHK ; LDA BK ; IS KING CMP SQUARE ; IN CHECK? BNE RETJ ; SET INCHEK=0 LDA #$00 ; IF IT IS STA INCHEK RETJ RTS ; ; IF A PIECE HAS BEEN CAPTURED BY ; A TRIAL MOVE, GENERATE REPLIES & ; EVALUATE THE EXCHANGE GAIN/LOSS ; TREE BVC RETJ ; NO CAP LDY #$07 ; (PIECES) LDA SQUARE LOOPX CMP BK,Y BEQ FOUNX DEY BEQ RETJ ; (KING) BPL LOOPX ; SAVE FOUNX LDA POINTS,Y ; BEST CAP CMP BCAP0,X ; AT THIS BCC NOMAX ; LEVEL STA BCAP0,X NOMAX DEC STATE LDA #$FB ; IF STATE=FB CMP STATE ; TIME TO TURN BEQ UPTREE ; AROUND JSR GENRM ; GENERATE FURTHER UPTREE INC STATE ; CAPTURES RTS ; ; THE PLAYER'S MOVE IS INPUT ; INPUT CMP #$08 ; NOT A LEGAL BCS ERROR ; SQUARE # JSR DISMV DISP LDX #$1F SEARCH LDA BOARD,X CMP DIS2 BEQ HERE ; DISPLAY DEX ; PIECE AT BPL SEARCH ; FROM HERE STX DIS1 ; SQUARE STX PIECE ERROR JMP CHESS ; ; GENERATE ALL MOVES FOR ONE ; SIDE, CALL JANUS AFTER EACH ; ONE FOR NEXT STEP ; ; GNMZ LDX #$10 ; CLEAR GNMX LDA #$00 ; COUNTERS CLEAR STA COUNT,X DEX BPL CLEAR ; GNM LDA #$10 ; SET UP STA PIECE ; PIECE NEWP DEC PIECE ; NEW PIECE BPL NEX ; ALL DONE? RTS ; -YES ; NEX JSR RESET ; READY LDY PIECE ; GET PIECE LDX #$08 STX MOVEN ; COMMON START CPY #$08 ; WHAT IS IT? BPL PAWN ; PAWN CPY #$06 BPL KNIGHT ; KNIGHT CPY #$04 BPL BISHOP ; BISHOP CPY #$01 BEQ QUEEN ; QUEEN BPL ROOK ; ROOK ; KING JSR SNGMV ; MUST BE KING! BNE KING ; MOVES BEQ NEWP ; 8 TO 1 QUEEN JSR LINE BNE QUEEN ; MOVES BEQ NEWP ; 8 TO 1 ; ROOK LDX #$04 STX MOVEN ; MOVES AGNR JSR LINE ; 4 TO 1 BNE AGNR BEQ NEWP ; BISHOP JSR LINE LDA MOVEN ; MOVES CMP #$04 ; 8 TO 5 BNE BISHOP BEQ NEWP ; KNIGHT LDX #$10 STX MOVEN ; MOVES AGNN JSR SNGMV ; 16 TO 9 LDA MOVEN CMP #$08 BNE AGNN BEQ NEWP ; PAWN LDX #$06 STX MOVEN P1 JSR CMOVE ; RIGHT CAP? BVC P2 BMI P2 JSR JANUS ; YES P2 JSR RESET DEC MOVEN ; LEFT CAP? LDA MOVEN CMP #$05 BEQ P1 P3 JSR CMOVE ; AHEAD BVS NEWP ; ILLEGAL BMI NEWP JSR JANUS LDA SQUARE ; GETS TO AND #$F0 ; 3RD RANK? CMP #$20 BEQ P3 ; DO DOUBLE JMP NEWP ; ; CALCULATE SINGLE STEP MOVES ; FOR K,N ; SNGMV JSR CMOVE ; CALC MOVE BMI ILL1 ; -IF LEGAL JSR JANUS ; -EVALUATE ILL1 JSR RESET DEC MOVEN RTS ; ; CALCULATE ALL MOVES DOWN A ; STRAIGHT LINE FOR Q,B,R ; LINE JSR CMOVE ; CALC MOVE BCC OVL ; NO CHK BVC LINE ; NOCAP OVL BMI ILL ; RETURN PHP JSR JANUS ; EVALUATE POSN PLP BVC LINE ; NOT A CAP ILL JSR RESET ; LINE STOPPED DEC MOVEN ; NEXT DIR RTS ; ; EXCHANGE SIDES FOR REPLY ; ANALYSIS ; REVERSE LDX #$0F ETC SEC LDY BK,X ; SUBTRACT LDA #$77 ; POSITION SBC BOARD,X ; FROM 77 STA BK,X STY BOARD,X ; AND SEC LDA #$77 ; EXCHANGE SBC BOARD,X ; PIECES STA BOARD,X DEX BPL ETC RTS ; ; CMOVE CALCULATES THE TO SQUARE ; USING SQUARE AND THE MOVE ; TABLE, FLAGS SET AS FOLLOWS: ; N - ILLEGAL MOVE ; V - CAPTURE (LEGAL UNLESS IN CH) ; C - ILLEGAL BECAUSE OF CHECK ; [MY THANKS TO JIM BUTTERFIELD ; WHO WROTE THIS MORE EFFICIENT ; VERSION OF CMOVE] ; CMOVE LDA SQUARE ; GET SQUARE LDX MOVEN ; MOVE POINTER CLC ADC MOVEX,X ; MOVE LIST STA SQUARE ; NEW POS'N AND #$88 BNE ILLEGAL ; OFF BOARD LDA SQUARE ; LDX #$20 LOOP DEX ; IS TO BMI NO ; SQUARE CMP BOARD,X ; OCCUPIED? BNE LOOP ; CPX #$10 ; BY SELF? BMI ILLEGAL ; LDA #$7F ; MUST BE CAP! ADC #$01 ; SET V FLAG BVS SPX ; (JMP) ; NO CLV ; NO CAPTURE ; SPX LDA STATE ; SHOULD WE BMI RETL ; DO THE CMP #$08 ; CHECK CHECK? BPL RETL ; ; CHKCHK REVERSES SIDES ; AND LOOKS FOR A KING ; CAPTURE TO INDICATE ; ILLEGAL MOVE BECAUSE OF ; CHECK SINCE THIS IS ; TIME CONSUMING, IT IS NOT ; ALWAYS DONE ; CHKCHK PHA ; STATE PHP LDA #$F9 STA STATE ; GENERATE STA INCHEK ; ALL REPLY JSR MOVE ; MOVES TO JSR REVERSE ; SEE IF KING JSR GNM ; IS IN JSR RUM ; CHECK PLP PLA STA STATE LDA INCHEK BMI RETL ; NO - SAFE SEC ; YES - IN CHK LDA #$FF RTS ; RETL CLC ; LEGAL LDA #$00 ; RETURN RTS ; ILLEGAL LDA #$FF CLC ; ILLEGAL CLV ; RETURN RTS ; ; REPLACE PIECE ON CORRECT SQUARE ; RESET LDX PIECE ; GET LOGAT LDA BOARD,X ; FOR PIECE STA SQUARE ; FROM BOARD RTS ; ; ; GENRM JSR MOVE ; MAKE MOVE GENR2 JSR REVERSE ; REVERSE BOARD JSR GNM ; GENERATE MOVES RUM JSR REVERSE ; REVERSE BACK ; ; ROUTINE TO UNMAKE A MOVE MADE BY ; MOVE ; UMOVE TSX ; UNMAKE MOVE STX SP1 LDX SP2 ; EXCHANGE TXS ; STACKS PLA ; MOVEN STA MOVEN PLA ; CAPTURED STA PIECE ; PIECE TAX PLA ; FROM SQUARE STA BOARD,X PLA ; PIECE TAX PLA ; TO SOUARE STA SQUARE STA BOARD,X JMP STRV ; ; THIS ROUTINE MOVES PIECE ; TO SQUARE, PARAMETERS ; ARE SAVED IN A STACK TO UNMAKE ; THE MOVE LATER ; MOVE TSX STX SP1 ; SWITCH LDX SP2 ; STACKS TXS LDA SQUARE PHA ; TO SQUARE TAY LDX #$1F CHECK CMP BOARD,X ; CHECK FOR BEQ TAKE ; CAPTURE DEX BPL CHECK TAKE LDA #$CC STA BOARD,X TXA ; CAPTURED PHA ; PIECE LDX PIECE LDA BOARD,X STY BOARD,X ; FROM PHA ; SQUARE TXA PHA ; PIECE LDA MOVEN PHA ; MOVEN STRV TSX STX SP2 ; SWITCH LDX SP1 ; STACKS TXS ; BACK RTS ; ; CONTINUATION OF SUB STRATGY ; -CHECKS FOR CHECK OR CHECKMATE ; AND ASSIGNS VALUE TO MOVE ; CKMATE LDX BMAXC ; CAN BLK CAP CPX POINTS ; MY KING? BNE NOCHEK LDA #$00 ; GULP! BEQ RETV ; DUMB MOVE! ; NOCHEK LDX BMOB ; IS BLACK BNE RETV ; UNABLE TO LDX WMAXP ; MOVE AND BNE RETV ; KING IN CH? LDA #$FF ; YES! MATE ; RETV LDX #$04 ; RESTORE STX STATE ; STATE=4 ; ; THE VALUE OF THE MOVE (IN ACCU) ; IS COMPARED TO THE BEST MOVE AND ; REPLACES IT IF IT IS BETTER ; PUSH CMP BESTV ; IS THIS BEST BCC RETP ; MOVE SO FAR? BEQ RETP STA BESTV ; YES! LDA PIECE ; SAVE IT STA BESTP LDA SQUARE STA BESTM ; FLASH DISPLAY RETP LDA #"." ; print ... instead of flashing disp Jmp syschout ; print . and return ; ; MAIN PROGRAM TO PLAY CHESS ; PLAY FROM OPENING OR THINK ; GO LDX OMOVE ; OPENING? BMI NOOPEN ; -NO *ADD CHANGE FROM BPL LDA DIS3 ; -YES WAS CMP OPNING,X ; OPPONENT'S BNE END ; MOVE OK? DEX LDA OPNING,X ; GET NEXT STA DIS1 ; CANNED DEX ; OPENING MOVE LDA OPNING,X STA DIS3 ; DISPLAY IT DEX STX OMOVE ; MOVE IT BNE MV2 ; (JMP) ; END LDA #$FF ; *ADD - STOP CANNED MOVES STA OMOVE ; FLAG OPENING NOOPEN LDX #$0C ; FINISHED STX STATE ; STATE=C STX BESTV ; CLEAR BESTV LDX #$14 ; GENERATE P JSR GNMX ; MOVES ; LDX #$04 ; STATE=4 STX STATE ; GENERATE AND JSR GNMZ ; TEST AVAILABLE ; MOVES ; LDX BESTV ; GET BEST MOVE CPX #$0F ; IF NONE BCC MATE ; OH OH! ; MV2 LDX BESTP ; MOVE LDA BOARD,X ; THE STA BESTV ; BEST STX PIECE ; MOVE LDA BESTM STA SQUARE ; AND DISPLAY JSR MOVE ; IT JMP CHESS ; MATE LDA #$FF ; RESIGN RTS ; OR STALEMATE ; ; SUBROUTINE TO ENTER THE ; PLAYER'S MOVE ; DISMV LDX #$04 ; ROTATE DROL ASL DIS3 ; KEY ROL DIS2 ; INTO DEX ; DISPLAY BNE DROL ; ORA DIS3 STA DIS3 STA SQUARE RTS ; ; THE FOLLOWING SUBROUTINE ASSIGNS ; A VALUE TO THE MOVE UNDER ; CONSIDERATION AND RETURNS IT IN ; THE ACCUMULATOR ; STRATGY CLC LDA #$80 ADC WMOB ; PARAMETERS ADC WMAXC ; WITH WEIGHT ADC WCC ; OF 0.25 ADC WCAP1 ADC WCAP2 SEC SBC PMAXC SBC PCC SBC BCAP0 SBC BCAP1 SBC BCAP2 SBC PMOB SBC BMOB BCS POS ; UNDERFLOW LDA #$00 ; PREVENTION POS LSR CLC ; ************** ADC #$40 ADC WMAXC ; PARAMETERS ADC WCC ; WITH WEIGHT SEC ; OF 0.5 SBC BMAXC LSR ; ************** CLC ADC #$90 ADC WCAP0 ; PARAMETERS ADC WCAP0 ; WITH WEIGHT ADC WCAP0 ; OF 1.0 ADC WCAP0 ADC WCAP1 SEC ; [UNDER OR OVER- SBC BMAXC ; FLOW MAY OCCUR SBC BMAXC ; FROM THIS SBC BMCC ; SECTION] SBC BMCC SBC BCAP1 LDX SQUARE ; *************** CPX #$33 BEQ POSN ; POSITION CPX #$34 ; BONUS FOR BEQ POSN ; MOVE TO CPX #$22 ; CENTRE BEQ POSN ; OR CPX #$25 ; OUT OF BEQ POSN ; BACK RANK LDX PIECE BEQ NOPOSN LDY BOARD,X CPY #$10 BPL NOPOSN POSN CLC ADC #$02 NOPOSN JMP CKMATE ; CONTINUE ;----------------------------------------------------------------- ; The following routines were added to allow text-based board ; display over a standard RS-232 port. ; POUT jsr pout9 ; print CRLF jsr pout13 ; print copyright JSR POUT10 ; print column labels LDY #$00 ; init board location JSR POUT5 ; print board horz edge POUT1 lDA #"|" ; print vert edge JSR syschout ; PRINT ONE ASCII CHR - SPACE LDX #$1F POUT2 TYA ; scan the pieces for a location match CMP BOARD,X ; match found? BEQ POUT4 ; yes; print the piece's color and type DEX ; no BPL POUT2 ; if not the last piece, try again tya ; empty square and #$01 ; odd or even column? sta temp ; save it tya ; is the row odd or even lsr ; shift column right 4 spaces lsr ; lsr ; lsr ; and #$01 ; strip LSB clc ; adc temp ; combine row & col to determine square color and #$01 ; is board square white or blk? beq pout25 ; white, print space lda #"*" ; black, print * db $2c ; used to skip over LDA #$20 POUT25 LDA #$20 ; ASCII space JSR syschout ; PRINT ONE ASCII CHR - SPACE JSR syschout ; PRINT ONE ASCII CHR - SPACE POUT3 INY ; TYA ; get row number AND #$08 ; have we completed the row? BEQ POUT1 ; no, do next column LDA #"|" ; yes, put the right edge on JSR syschout ; PRINT ONE ASCII CHR - | jsr pout12 ; print row number JSR POUT9 ; print CRLF JSR POUT5 ; print bottom edge of board CLC ; TYA ; ADC #$08 ; point y to beginning of next row TAY ; CPY #$80 ; was that the last row? BEQ POUT8 ; yes, print the LED values BNE POUT1 ; no, do new row POUT4 LDA REV ; print piece's color & type BEQ POUT41 ; LDA cpl+16,X ; BNE POUT42 ; POUT41 LDA cpl,x ; POUT42 JSR syschout ; lda cph,x ; jsr syschout ; BNE POUT3 ; branch always POUT5 TXA ; print "-----...-----" PHA LDX #$19 LDA #"-" POUT6 JSR syschout ; PRINT ONE ASCII CHR - "-" DEX BNE POUT6 PLA TAX JSR POUT9 RTS POUT8 jsr pout10 ; LDA $FB JSR syshexout ; PRINT 1 BYTE AS 2 HEX CHRS LDA #$20 JSR syschout ; PRINT ONE ASCII CHR - SPACE LDA $FA JSR syshexout ; PRINT 1 BYTE AS 2 HEX CHRS LDA #$20 JSR syschout ; PRINT ONE ASCII CHR - SPACE LDA $F9 JSR syshexout ; PRINT 1 BYTE AS 2 HEX CHRS POUT9 LDA #$0D JSR syschout ; PRINT ONE ASCII CHR - CR LDA #$0A JSR syschout ; PRINT ONE ASCII CHR - LF RTS pout10 ldx #$00 ; print the column labels POUT11 lda #$20 ; 00 01 02 03 ... 07 jsr syschout txa jsr syshexout INX CPX #$08 BNE POUT11 BEQ POUT9 POUT12 TYA and #$70 JSR syshexout rts Pout13 ldx #$00 ; Print the copyright banner Pout14 lda banner,x beq POUT15 jsr syschout inx bne POUT14 POUT15 rts KIN LDA #"?" JSR syschout ; PRINT ONE ASCII CHR - ? JSR syskin ; GET A KEYSTROKE FROM SYSTEM AND #$4F ; MASK 0-7, AND ALPHA'S RTS ; ; 6551 I/O Support Routines ; ; Init_6551 lda #$1F ; 19.2K/8/1 sta ACIActl ; control reg lda #$0B ; N parity/echo off/rx int off/ dtr active low sta ACIAcmd ; command reg rts ; done ; ; input chr from ACIA1 (waiting) ; syskin lda ACIASta ; Serial port status and #$08 ; is recvr full beq syskin ; no char to get Lda ACIAdat ; get chr RTS ; ; ; output to OutPut Port ; syschout PHA ; save registers ACIA_Out1 lda ACIASta ; serial port status and #$10 ; is tx buffer empty beq ACIA_Out1 ; no PLA ; get chr sta ACIAdat ; put character to Port RTS ; done syshexout PHA ; prints AA hex digits LSR ; MOVE UPPER NIBBLE TO LOWER LSR ; LSR ; LSR ; JSR PrintDig ; PLA ; PrintDig AND #$0F ; prints A hex nibble (low 4 bits) PHY TAY ; LDA Hexdigdata,Y ; PLY jmp syschout ; Hexdigdata asc "0123456789ABCDEF" banner asc "MicroChess (c) 1996-2005 Peter Jennings, www.benlo.com" db $0d, $0a, $00 cpl asc "WWWWWWWWWWWWWWWWBBBBBBBBBBBBBBBBWWWWWWWWWWWWWWWW" cph asc "KQRRBBNNPPPPPPPPKQRRBBNNPPPPPPPP" db $00 ; ; end of added code ; ; BLOCK DATA *= $1580 SETW db $03, $04, $00, $07, $02, $05, $01, $06 db $10, $17, $11, $16, $12, $15, $14, $13 db $73, $74, $70, $77, $72, $75, $71, $76 db $60, $67, $61, $66, $62, $65, $64, $63 MOVEX db $00, $F0, $FF, $01, $10, $11, $0F, $EF, $F1 db $DF, $E1, $EE, $F2, $12, $0E, $1F, $21 POINTS db $0B, $0A, $06, $06, $04, $04, $04, $04 db $02, $02, $02, $02, $02, $02, $02, $02 OPNING db $99, $25, $0B, $25, $01, $00, $33, $25 db $07, $36, $34, $0D, $34, $34, $0E, $52 db $25, $0D, $45, $35, $04, $55, $22, $06 db $43, $33, $0F, $CC ; ; ; end of file ;