xa-2.3.8/0000700000031500000010000000000013125355333011437 5ustar spectrestaffxa-2.3.8/COPYING0000600000031500000010000004312207615405420012476 0ustar spectrestaff 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) 20yy 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) 20yy 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. xa-2.3.8/ChangeLog0000600000031500000010000002651113125355426013223 0ustar spectrestaffxa-2.1.0 * Rewrite of command line option handling to better look like usual (cc) options. * Removed ^M from all files. * Removed all external declarations to header files, and made all static functions static. | Now compiles almost without warning with 'gcc -W -Wall'. -- André Fachat 31 Oct, 1996 xa-2.1.0a * Introduced concept of code relocation. Now each label being set to the program counter is a 'pointer', that gets an entry in a relocation table. Simple arithmetic operations are allowed. The relocation table is still just printed unsortedly. -- André Fachat 31 Oct, 1996 xa-2.1.0b * Produces some preliminary kind of relocatable file, including header etc. Problems -- relocation table does as if file is assembled for address 0. Need a) a better way to set program counter. b) pseudo opcodes for distinguishing segments. c) a way to temporarily disable relocation. d) a way to include extra headers and options into the file. -- André Fachat 31 Oct, 1996 * Assembler now produces a relocatable file format, as described in the file ``fileformat.txt''. Temporarily disabling relocation is with the ``*=value'' directive, while switching back to relocation mode goes with ``*='' (without value). New pseudo opcodes ``.text'', ``.data'', ``.bss'', ``.zero'' switch between the segments. -- André Fachat 02 Nov, 1996 xa-2.1.0e * There was a bug in the arithmetic routine that had set all pointer to the text segment, if something was added. * There also was a bug in the loader when actually using options. * A new pseudo opcode was added -- ``.fopt''. | Works like ``.byte'', but puts these bytes in a file option. | The length in the file option is automagically set. ``.fopt'' | may appear anywhere in the file, but it should be at the | beginning | (might be mandatory in a later version). -- André Fachat 06 Nov, 1996 xa-2.1.0f * Added a command line switch ``-M'' to ignore colons in a comment after a semicolon. * Without it, a colon separates complete mnemonics, including the semicolon comment. | Well, actually this switch is a ``MASM'' compatibility switch, and will surely be expanded someday, when I get more info on MASM. * Now ``*'' and ``='' can be separated for the definition of the program counter and ``.byte'' is also accepted. This makes it more MASM compatible. ".end" is ignored. Still missing is ``.include''. -- André Fachat 11 Nov, 1996 xa-2.1.0g * Started working on ``official'' o65 fileformat. If there are no undefined labels, and no relocated code is embedded in absolute code, the thing should work. -- André Fachat 21 Dec, 1996 xa-2.1.1 * ``.dsb'' now has an _optional_ parameter ``fillbyte''. * Undefined references are now put into the relocation table (i.e. handled correctly) if the ``-c'' option is given. * The file format conforms to o65 version 1 file format. * Embedding absolute in relocatable code and vice versa is buggy... -- André Fachat 21 Dec, 1996 xa-2.1.1a * Embedding absolute code in relocatable seems to work now. -- André Fachat 21 Dec, 1996 xa-2.1.1e * The option to embed relocatable code in absolute code has been dropped. Therefore the command line options ``-A'' (make it romable), ``-b?'' (set segment start addresses), and ``-G'' (omit exported globals from file) have been added. * Internally, the whole thing has been made dynamic; except for the preprocessor (and the storage between pass1 and pass2), everything uses dynamically allocated tables. m_alloc, which had been introduced long time ago because of the buggy malloc on the Atari ST is gone now! -- André Fachat 22 Dec, 1996 xa-2.1.1f * Added the ``-a'' and ``-A'' options to file65, so that it can now print the start addresses for following files in the ROM when making romable code. * Added shell (bash) script ``mkrom.sh'' that assembles a given list of files and builds a ROMable file. The first two bytes are single linked list pointers, and then comes the file. -- André Fachat 02 Jan, 1997 xa-2.1.1g * Added the file ``reloc65'', to relocate o65 files without reassembling them. * Fixed quite some bugs in xa (segment numbering in the globals list and switched low/high byte relocation entry type in relocation table. Now conforms to documentation, i.e. fileformat.txt) -- André Fachat 03 Jan, 1997 xa-2.1.2 * Added ``ld65'', a simple linker for o65 files. * Another bug in xa fixed now. -- André Fachat 04 Jan, 1997 xa-2.1.3 * Allows to use ``.data'' etc in absolute mode, too. No relocation entries are generated then. Segment start can be set with ``-b?'' command line options, though. Also the data segment is discarded with this method! This allows to use the normal ``.data'' etc syntax even when assembling a ROM (which is done in absolute mode.) * Fixed a bug where ``.dsb'' in a data segment didn't fill with the right value -- André Fachat 25 Mar, 1997 xa-2.1.3e * Added preprocessor continuation lines, and .block and .bend pseudo-opcodes (They map to ``.('' and ``.)'' respectively.) -- André Fachat 27 Jul, 1997 xa-2.1.4 * Do not leave output file around after an error -- this is better for ``make''. * Also it seems to have settled for a while, so I can release a new version. -- André Fachat 11 Sep, 1997 xa-2.1.4c * Fixed a nasty bug that prevented correct relocation table entries when a ``label2=label1'' contruct was used and ``label2'' was accessed. * Added ``-I'' option. -- André Fachat 30 Dec, 1997 xa-2.1.4d * fixed align code. Now inserts NOP opcodes into text segment, and sets file mode appropriately. -- André Fachat 26 Jan, 1998 xa-2.1.4e * Changed o65 fileformat and adopted it in xa. -- André Fachat 26 Jan, 1998 xa-2.1.4g * Fix handling of !zeropageaddress, that was broken (did not result in absolute address, but gave error message.) * Add cross reference list to labels if switched on on command line. * Fix the filename when multiple files are given on the command line (used to give the first filename for all errors in second pass.) -- André Fachat 25 Nov, 1998 xa-2.1.4h * In file65 added support for undefined labels and globals, also for (some known) file options. * Fix a preprocessor bug. -- André Fachat 12 Dec, 1998 xa-2.2.0-p1-1 * Update COPYING to the latest version (Y2K-fixed + new address to GNU) * Lots of fixes to the Makefiles * Cleaned up the structure of the TODO file * Added manual-pages for file65, ld65, printcbm, reloc65, uncpk, and xa * Commented out LIB-flags -lm, -lcurses and -ltermcap, since they are all unused * Added `--help' and `--version' to all binaries * Removed `-h', `-?' and `-v' options where applicable * Created a file containing the version-function; version.h * Moved common macros to a separate file; xad.h * Restructuring of printcbm to become more readable * Added ifndef/define/endif traps to all header-files * Fixed a few typos * Renamed romadr to romaddr * Renamed all functions matching *such* to *search* * Fixed all warnings * Cleaned up all header-files * Reformatted xa.log -- David Weinehall 20 Aug, 2002 xa-2.3.0 * Version number jump for all the unofficial xa's out there * Fixed addressing bugs for @, ! and completed 65816 merge Thanks to David for the report * Moderate legibility overhaul to xat.c (will continue on this) * More compiler warnings corrected Thanks to David for the report * man files completed * Documentation updated * Last line bug corrected (where last line not assembled if no newline) Thanks to silverdr for the report * ld65 is now ldo65 to avoid conflicts with cc65 package * Post-defined labels work better, or at least somewhat (no longer attempts to optimize in pass 2 and generate bad code). Can be forced with ` Thanks to silverdr for the report * Makefile bugs multiplied * @ now mostly obligatory for 24-bit addressing -- Cameron Kaiser 2 Apr, 2006 xa-2.3.2 * Introduced switch to convert values in quotes to different character sets. Currently supported are ASCII (default) and PETSCII * Fixed some quote bugs -- André Fachat 23 Dec, 2006 Thomas Giesel's reports and suggestions, thank you: * -M works on colons in comments and nowhere else, as documented * macro function arguments are properly recursively evaluated * cpp output now grokked for more complex pre-parsing, rather than reinvent the wheel Other things: * .xl, .xs, .al, .as weren't documented, and now they are (always worked) for 65816 mode * ! for forward-defined labels calculated wrong instruction length, fixed * xap.c cleaned up some, xat.c cleaned up some more Legibility work is going to be a long-term project. * -x is now deprecated * Documentation updated -- Cameron Kaiser 13 Jan, 2007 xa-2.3.3 * Compatibility update for Microsoft Visual Studio and mingw/MSYS (thanks Fabian Nunez and Mikkel Holm Olsen). -- Cameron Kaiser 15 May, 2007 xa-2.3.4 * -p to define alternate synonym for # for preprocessor to avoid cpp/xa preprocessor clashes and messes. * Direct linking into output stream of binary files (.bin). * Minor overhaul of error system to facilitate future expansion. * Documentation updated. -- Cameron Kaiser 1 July, 2008 xa-2.3.5 Most of this was suggested by Martin Wendt. * Fixed bug where .bin was affected by the current character set. * Added PETSCREEN and HIGH character sets. * Added .aasc. * Some more legibility work. * Documentation updated. -- Cameron Kaiser 7 February, 2009 xa-2.3.6 * 'make test' for regression testing framework (requires Perl). * Changed getline() to xa_getline() to avoid collision with glibc 2.10+ * Fixed compile problems with misc/. * Fixed message offsets. -- Cameron Kaiser 11 July 2014 xa-2.3.7 * Fixed buffer overflow and test failure with gcc 4.9 (thanks Adam Sampson). * mvn and mvp now use the standard syntax (thanks Alessandro Gatti). * Copyright message is no longer put in the error log to simplify testing. * Makefile properly triggers a relink for testing or source changes. * Spurious messages quelled. * Documentation updated. * Testsuite expanded. -- Cameron Kaiser 29 December 2014 xa-2.3.8 * Fixed issue with colons in string literals being treated as separators (thanks Simon Rowe). * Testsuite expanded. -- Cameron Kaiser 29 June 2017 xa-2.3.8/Makefile0000600000031500000010000000307313125350713013101 0ustar spectrestaff# Unix gcc or DOS go32 cross-compiling gcc # CC = gcc LD = gcc # for testing. not to be used; build failures in misc/. #CFLAGS = -O2 -W -Wall -pedantic -ansi CFLAGS = -O2 LDFLAGS = -lc # for DOS? # CC = gcc-go32 # LD = gcc-go32 # CFLAGS = -W -Wall -pedantic # Other cc #CC = cc #CFLAGS = #LD = ld DESTDIR = /usr/local BINDIR = $(DESTDIR)/bin MANDIR = $(DESTDIR)/share/man/man1 DOCDIR = $(DESTDIR)/share/doc MKDIR = mkdir -p INSTALL = install all: killxa xa uncpk killxa: rm -f xa xa: (cd src && LD=${LD} CC="${CC} ${CFLAGS}" ${MAKE}) load: (cd loader && CC="${CC} ${CFLAGS}" ${MAKE}) uncpk: (cd misc && CC="${CC} ${CFLAGS}" ${MAKE}) dos: clean (cd src && LD=gcc-go32 CC=gcc-go32 CFLAGS="-W -Wall -pedantic" ${MAKE}) (cd misc && CC=gcc-go32 CFLAGS="-W -Wall -pedantic" ${MAKE}) rm -f xa file65 ldo65 uncpk printcbm reloc65 mkrom.sh src/*.o mingw: clean (cd src && LD=${LD} CC=${CC} CFLAGS="${CFLAGS}" LDFLAGS="" ${MAKE}) (cd misc && LD=${LD} CC=${CC} CFLAGS="${CFLAGS}" LDFLAGS="" ${MAKE}) clean: (cd src && ${MAKE} clean) (cd loader && ${MAKE} clean) (cd misc && ${MAKE} mrproper) rm -f xa *.exe *.o65 install: xa uncpk $(MKDIR) $(BINDIR) $(MKDIR) $(MANDIR) $(INSTALL) xa reloc65 ldo65 file65 printcbm uncpk $(BINDIR) $(INSTALL) man/file65.1 man/ldo65.1 man/printcbm.1 man/reloc65.1 man/uncpk.1 man/xa.1 $(MANDIR) #$(MKDIR) $(DOCDIR)/xa65 dist: clean #cd .. ; tar cvf xa-2.3.8A.tar xa-2.3.8 ; gzip xa-2.3.8A.tar cd .. ; tar cvf xa-2.3.8.tar xa-2.3.8 ; gzip xa-2.3.8.tar test: xa uncpk cd tests && ./harness -make="$(MAKE)" -cc="$(CC)" -cflags="$(CFLAGS)" xa-2.3.8/README.1st0000600000031500000010000001203713125350776013040 0ustar spectrestaffThis is the readme for xa, a cross-assembler for the 6502 and 65816 CPUs (and derivatives). xa is a small, fast, portable two-pass assembler that compiles under most ANSI C compilers. It is distributed under the GNU Public License (see COPYING). The current version is 2.3.8, a bug fix to the long-lived 2.3.0, itself with compatibility improvements and new man-based documentation. It also completed the merge of the 65816 and 6502/R65C02 versions and thus the current xa can generate code for all targets now. To install on a generic Unixy thing, you should be able to just type % make # to build the executable, and if it works ... % make test # if you have Perl, make and prerequisites, otherwise % make install # to install man pages and binaries into the system This will create xa along with its various support utilities. Try assembling the cpk depacker in examples/ as a test. xa also comes with uncpk (a program for generating cpk archives) and printcbm (a program for listing Commodore BASIC test) and file65, ldo65 and reloc65 for displaying, linking and relocating o65 files in Andre's relocatable format (see doc/fileformats.txt). The loader/ directory also has goodies for managing relocatable binaries. Don't forget the man pages in man/. Install these into your MANPATH at your leisure, or read them with nroff -man (and/or groff -man). xa is no longer broadly supported outside of Unix due to my inability to test it, but has nothing that should impair it from compiling elsewhere. To wit, DOS compilation is still supported with the GO32 package. You should just be able to type C:\> make dos In addition, there are compatibility updates to allow it to compile under Microsoft Visual Studio and mingw. It should compile under VS2005 as written; look in the vstudio directory for solution and project files provided by Fabian Nunez. For mingw, use make mingw Similarly, Amiga and Atari ST compilation should still also function with their particular compatible packages. xa has a companion disassembler, the dxa package. dxa is not included in the standard xa distribution, but can be downloaded from the xa home page at http://www.floodgap.com/retrotech/xa/ Please check by periodically for the latest version of both packages. xa was originally written and maintained by Andre Fachat. The current version is maintained by Cameron Kaiser. Please send me your comments at ckaiser@floodgap.com -- Andre's original readme follows and applies generally to the present version. ------------------------------------------------------------------------------- XA is a 6502 cross compiler: - under GNU public license - can produce _relocatable_ binaries - The full fileformat description and 6502 file loader included. - also included relocation and info utilites, as well as linker - for any ANSI-C compliant computer (only utilities need 'stat' call for file size). - fast by hashtables - Rockwell CMOS opcodes - running under DOS and any ANSI C system (Unix, Amiga, Atari ST) I developed this cross assembler for the 6502 CPU family quite some time ago on my Atari ST. The assembler has successfully been ported to Amiga and Unix computer (ported? just compiled... :-) Lately I came across the problem to need relocatable 6502 binary files, so I revised the assembler from version 2.0.7 to 2.1.0, adding a (admittedly proprietary) 6502 relocatable binary format. But there are not many other formats around and they didn't fit my needs. I have developed this format myself and it is under the GNU public license. With version 2.1.1 the 'official' version of the fileformat is supported. To compile it, just type "make" (if you have the GNU gcc. If not, edit the Makefile for the compiler options). This produces "xa", the cross assembler; "uncpk", a small packing utility (where the C64 counterpart is in the examples subdirectory), "printcbm", that lists C64 BASIC files and 'file65' that prints some information about o65 files. The "loader" in the loader subdirectory is a basic 6502 implementation of a relocating binary loader. "file65" prints file information on 'o65' relocatable files. "reloc65" can relocate 'o65' files. If you want to use it under DOS, you have to have the GO32 DOS crosscompiling tools to compile. Then just type "make dos" and you'll end up with the appropriate DOS binaries. This has been tested only under i386 Linux, however. Another archive with the DOS binaries included is provided. One problem on the Atari was it's broken "malloc". Therefore I used to alloc everything in one chunk and divide the memory by hand. So everything was kind of statically allocated. This is almost gone now. Only the temporary storage between pass1 and pass2 and the preprocessor are still allocated in one chunk (size definitions in xah.h). The rest is allocated as needed. The docs are in the 'doc' subdir. There also is a description of the 6502 relocatable binary format. If you think some things could be expressed in a better way, feel free and mail me to improve my english ;-) [ The documentation is now maintained in man(1) format in man/ . -- CK ] Andre xa-2.3.8/TODO0000600000031500000010000000043411021525754012131 0ustar spectrestaffo nm65 that prints labels from o65 files o `-L' option for ldo65, such that globals can be suppressed, but KERNEL can be kept o inc a -> ina, dec a -> dea (right now uses bare inc and dec) o VICE label file support o Smarter -X that can cope with non-block-aligned segment sizes xa-2.3.8/doc/0000700000031500000010000000000010546754737012223 5ustar spectrestaffxa-2.3.8/doc/README0000644000031500000010000000040510416504534013074 0ustar spectrestaffAs of 2.3.0, the official documentation will be maintained in the ../man/ directory. However, as the feature set is mostly mature, there is likely to be little difference. The 2.2.x documents are here for your interest and historical reference. Cameron Kaiser xa-2.3.8/doc/fileformat.txt0000600000031500000010000005755006463156023015115 0ustar spectrestaff 6502 binary relocation format V1.2 as of 26jan1998 (c) André Fachat (a.fachat@physik.tu-chemnitz.de) _________________________________________________________________ Changes from V1.1 The order for saving the undefined reference and the low byte of a high byte relocation entry has changed. This makes the OS/A65 lib6502 implementation easier. How many other people use this format anyway...? _________________________________________________________________ 0) Preface With some new 6502/C64/C128 operating systems comes the need for a new binary format. In multitasking operating systems like Lunix, SMOS, or OS/A65, a binary file cannot be loaded to a fixed location that might already be used by another program. Therefore it must be possible to relocate the program to an arbitrary address at least at load time. In addition to that, more specific information might be stored in a binary executable file, like interrupt vectors for example. This text gives a good solution to this problem for the 6502 CPU and an assembler source format to use this format in a general manner. The file format can even be used as an object file format, i.e. a format a linker can use as an input file. It is also usable as a 65816 file format. Instead of zeropage addressing modes, the 65816 has direct addressing modes, that add the contents of the direct register to the zeropage address in the opcode. 1) 6502/65816 specifics The 6502 has the special feature of a 'zeropage', i.e. a very limited memory address range used for special addressing modes. So the format should not only provide a means to relocate absolute addresses but also zeropage addresses. The 65816 replaces zeropage addressing with direct addressing modes. The stack space is also very limited. A binary format has to provide a measure of how much stack space is needed for the application. Such limits should be defined as 2 byte values, even if the 6502 only has a range of 8 address bits for zeropage and stack. But the 65816 behaves differently, it has a 16 bit stack pointer for example. For further expandability, a 32 bit format should be provided, although the 16 bit format suffices for the 65816 already. Another problem is, that an address can be 'split', i.e. you can just use the high byte or the low byte separately in an opcode. This gives need to a special relocation table format, that can cope with half-address references. The 65816 can even have three byte addresses, i.e. address in a segment and segment number. 2) binary format 2.1) General The file differs from the known Commodore file formats, in that a lot more information is stored in the file. First the data is structured in separate segments to allow different handling of text (program code), data (like tables) and bss (uninitialized data). Also tables are included to allow late binding, i.e. linking the file with other files at load time, and relocation, i.e. executing the file at different addresses in 6502 address space. 2.2) Segments As already used in other formats, the assembler uses three different segment types, i.e. text (the actual program code), data (initialized variables), and bss (uninitialized variables). To have these different segments seems to be 'overdesigned', but they actually make memory handling easier in more complex operating systems on systems with virtual addresses (OS/A65, for example). The text segment is defined to be read-only memory. This doesn't allow self-modifying code in this segment, but allows memory sharing in virtual memory architectures. The data segment actually is like the text segment, only it is allocated writable. This segment might not be shared between different processes. The contents of these two segments are loaded from the file. The bss segment is uninitialized data, i.e. upon program start, it is not defined - and not loaded from the file. This area is read-write and can be used during program execution. It is also not shared between processes. In addition to these segments, the 6502 format also includes a zeropage segment type, to allow zeropage variables to be relocated. This zeropage segment is like a bss segment, in that only the length, but not the data is saved. For the 65816 the zeropage segment changes its meaning to a bank zero segment. The different segments hold different type of data and can be located anywhere in memory (except zero segment, which has to be in the zeropage resp. bank zero). The program must therefore not assume anything about the relative addresses between different segments. 2.3) Relocation In general, there are three ways to handle the relocation problem so far: - Tables: have a relocation table for a text segment if the relocation table is put in front of code you have to save the table in a side-storage if table is behind, you still cannot relocate 'on the fly'. - Deassembling: go through the code, deassemble it and change all absolute addresses. Problem: needs to know or have hints about where some data is in the code. - Relocation info in the code: here each address is preceeded with an 'escape' code and is relocated when loading. But this disallows block oriented transfer from storage media to memory. This binary format uses the first method, with the table after the code/data. This way block oriented transfer for the text/data segment can be used. And while reading the relocation tables bytewise, the relocation can be done without the need to save the table somewhere. 2.4) External References & Exported Globals As this file format should not only be used as an executable format, but also as object file format, it must provide a way to define references - references exported from this object and labels referenced in this object. The external references list (also called 'undefined list') lists the addresses where labels not defined in this object are referenced. The exported globals list lists the addresses that are available for other objects. The labels are named by null-terminated ASCII strings. Even an executable file can have non-empty globals and externals lists, but only if the operating system allows this. In this case, so called 'late binding' is used to link the object with some global libraries at link time. 2.5) File extension The proposed standard extension for the described format is ".o65" when used as an object file. 2.6) Format description The binary format is the following: ( header text segment data segment external references list relocation table for text segment relocation table for data segment exported globals list ) The description of the parts follows: 2.6.1) Header The header contains the minimum needed data in a fixed struct. The rest of the necessary information is put into the header options. [Note: .word is a 16 bit value, low byte first, .byt is a simple byte. .long is a 32 bit value, low byte first. .size is a 16 or 32 bit value according to .word and .long, depending on the size bit in the mode field ] This is the fixed struct: ( .byt $01,$00 ; non-C64 marker .asc "o65" ; o65 MAGIC! .byt 0 ; version .word mode ; mode word .size tbase ; address to which text is assembled to ; originally .size tlen ; length of text segment .size dbase ; originating address for data segment .size dlen ; length of data segment .size bbase ; originating address for bss segment .size blen ; length of bss segment .size zbase ; originating address for zero segment .size zlen ; length of zero segment .size stack ; minimum needed stack size, 0= not known. ; the OS should add reasonable values for ; interrupt handling before allocating ; stack space ) The mode word currently has these defined bits: mode.15 : CPU 0= 6502 1= 65816 mode.14 : reloc 0= bytewise... 1= page(256byte)wise relocation allowed mode.13 : size 0= size=16 bit, 1= size=32 bit mode.12 : obj 0= executable 1= object file mode.0-1: align 0= byte align, 1= word (i.e. 2 byte) align 2= long (4 byte) align 3= block (256 byte) align The CPU bit tells the loader for which CPU the file was made. This has implications on the zero segment, for example. Also a system can check if the program will run at all (on a 6502 that is). The reloc bit defines if an object file can be relocated bytewise, or if it must be page-aligned. A page has 256 bytes. The restriction to pagewise relocation simplifies the relocation table and also allows simpler compilers/assemblers. The size bit determines the size of the segment base address and length entries. Currently the 16 bit size (size bit = 0) works for 6502 and 65816 CPUs. The obj bit distinguishes between object files and executables. An object file is used as assembler output that can be linked with other object files to build an executable or an object library. The two align bits give the address boundary the segments can be placed. Even the 6502 needs this, as, for example, "jmp ($xxFF)" is broken. The align bits are valid for all of the segments. [Note: if reloc=1, then align should be 3. But if align=3, reloc need not be 1, because reloc switches to a simpler version of the relocation table. The reloc bit might be obsoleted in newer versions of this format. Though it should be set, if necessary.] All unused bits in the mode field must be zero. Note that the header size is 26 if the size bit is zero and 44 if the size bit is one. The fixed sized struct is immediately followed by a list of header options. Each header option consists of a single byte total length, a type byte and some data bytes if needed. A single length byte of $00 ends the header option list. ( { ; optional options, more than one allowed .byt olen ; overall length (including length and type ; byte .byt otype ; option type [ .byt option_bytes ] } .byt $00 ; end of options marker (i.e. option len=0) ) The header options currently defined/proposed are: - Filename: type=0; len=strlen(filename_in_ascii)+3; content="filename_in_ascii",0 The string contains the name of the object. - Operating System Header type=1; len=? the first data byte is the OS type: 1 OSA/65 header supplement 2 Lunix header supplement [others to follow?] the following data contains OS specific information. A suggested data byte is the OS version as second byte. - Assemblerprogram: type=2; len=strlen(ass)+3; content="ass",0 The string contains the name of the assembler resp. linker that produced this file/object. For example (syntax see below) .fopt 2, "xa 2.1.1g",0 becomes 0c 02 78 61 20 32 2e 31 2e 31 67 00 in the file. - Author: type=3; len=strlen(author)+3; content="author",0 The string contains the author of the file. - Creation data: type=4; len=strlen(date)+3; content="date_string",0 The string contains the creation date in format like: "Sat Dec 21 14:00:23 MET 1996", where we have the day, Month, date, time, timezone and year. See output of `date`... 2.6.2) text and data segments The text and data segments are just the assembled code. The only difference between text and data segments is the read/write mode of the two segments. Therefore, to be compliant to this file format, self-modifying code goes into the data segment. 2.6.3) Undefined references list The next list is an ASCII list of labels that are referenced in this file but not defined. The lists is preceeded with the number of undefined labels (16 or 32 bits, according to the mode.size bit). undef_list: number_of_undefined_labels.s "undefined_label1",0 "undefined_label2",0 ... 2.6.4) Relocation tables The relocation tables are the same format for the two segments, text and data. In general a relocation entry consists of the offset from the previous relocation address to the next one, the type of the relocation and additional info. Relocation not only defines the relocation when moving object code to a different address, but also filling in the undefined references. Each table starts at relocation address = segment base address -1. I.e. if the segment base address is $1000 for example, the first entry has an offset computed from base address-1 = $0fff. The offset to the next relocation address is the first byte of each entry. If the offset is larger than 254 (i.e. 255 or above), than a 255 is set as offset byte, the offset is decremented by 254 (note the difference) and the entry is started again. { [255,...,255,] offset of next relocation (b), typebyte|segmentID [, low_byte] }+ where typebyte has the bits 5, 6 and 7 and is one of WORD $80 2 byte address HIGH $40 high byte of an address LOW $20 low byte of an address SEGADR $c0 3 byte address (65816) SEG $a0 segment byte of 3 byte address The segmentID stands for the segment the reference points to: 0 undefined 1 absolute value 2 text segment 3 data segment 4 bss segment 5 zero segment (Of course the absolute value will never appear in a relocation table, but this value is necessary for the exported list) If the type is HIGH, the low byte of the value is stored behind the relocation table entry, if bytewise relocation is allowed (header mode field bit 14). If only pagewise relocation is allowed, then only HIGH relocation entries can occur, and the low byte is implicitely set zero (i.e. it is _not_ saved in the relocation table). If the type is SEG, then the two lower bytes of the three byte segment address are stored behind the entry in the relocation table, lower byte first. If the segment is "undefined", the typebyte is immediately followed by the two (mode size=0) or four (mode size=1) byte value index in the undefined references list. If it is a high byte relocation, the low byte is saved behind the index value. The index value determines the undefined reference, which must be looked up by the loader. The value taken from the relocation address in the segment, together with the low byte from the relocation table (if HIGH entry) form the address used if the segment would be used unrelocated. To relocate the segment, the difference between the relocated segment base address and the segment base address from the file is then added to the above address. The result is again saved in the segment. A zero offset byte ends the relocation table. The first offset is computed from the segment base address-1, to avoid a 0 value in the first entry. Note that direct addressing modes do not generate entries in the relocation table. instead it is assumed that the 65816 direct register holds the correct value (i.e. zero segment base address) when running this program. Example: Segment Base address in file (header.tbase) is $1000. The start address of the text segment after relocation is real.tbase = $1234. Now the first (unrelocated) address at which a relocation should take place is here: $1222 A9 23 lda #>vector This generates the offset: $1222-($1000-1) = $223. This is larger than 254 ($fe), so the first byte is 255 ($ff). The offset is decremented by $fe, and gives $125. This again is larger than $fe, so the next byte is $ff again. After substracting $fe again, we have $27. But this is the address of the opcode. To get the address of the address byte, we have to add 1 to get $28, which becomes the third byte. The next offset is then computed from $1223, because this is the last relocation address. Now we reference the high byte of an address, lets say vector=$23d0 (not relocated), in the text segment. Therefore the relocation type becomes 'HIGH | text_segmentID = $42', which is the next byte. Because we are referencing a high byte of an address, the low byte of the unrelocated address is saved behind the typebyte in the relocation entry. This byte is missing when referencing a low byte or address. The relocation table entry is now: $ff, $ff, $28, $42, $d0. When actually doing the relocation, the relocation pointer is initialized to real.tbase-1 = $1233. Then we compute the offset to $224, which brings us to $1457, where the address byte of the above opcode is after loading the file to $1234. We now have to compute the new address, where vector is after relocation. So we take the unrelocated low byte from the relocation table ($d0) and the high byte from $1457 ($23). vector_file = ($23 To this value we add the difference between the address the program is assembled to and the real load address: vector_relocated = vector_file + (real.tbase - header.tbase) = $23d0 + ($1234 - $1000) = $23d0 + $234 = $2604 From this value the high byte is then written back to the address $1457. Had we not saved the low byte in the relocation table, and only added the high bytes, we would have missed the carry bit that increments the high byte in this case! Had "vector" now been an undefined reference, and "vector" would be the second label in the undefined references list, we would get the following relocation table entry (assuming mode.size=0): $ff, $ff, $28, $40, $00, $02, $00 The value computed with the above formula for vector_file is now added to the address the label "vector" now really has (This must of course be looked up into an external table or list). Had the opcode been "LDA #>vector+$567", then the low byte in the relocation table would be $67, while the high byte in the opcode would be $05. This value would result in vector_file and the real address of "vector" would be added before wrting back the high byte to the opcode. 2.6.5) exported globals list The global list is a list of names, together with the target segment and the offset in the segment for each name. It is preceeded with the number of exported labels. This allows the loader to allocate a table large enough, if needed. The number of labels and the offset value are 16 bit or 32 bit values according to the size bit in the header mode field. The segmentID is a byte value and the same as in the relocation table entry (see section 2.6.3). number_of_exported_labels.s "global_label_name_in_asc1",0, segmentID.b, value.s ... 3) assembler source format The assembler source format is a suggestion only. It will be implemented in xa65, a cross assembler for 6502 CPUs running on Unix/Atari ST/Amiga as a reference platform. The assembler provides a way to embed absolute address code in relocatable code. This is needed when code should be copied to a specific location known at assemble time. There also is a way to make a file 'romable'. You can give the start address of the _file_ in ROM, and the assembler automatically sets the text segment start address to where the code will be in the ROM. Of course, the other segments must be taken care of with -b? command line parameter, that set the segment start address. 3.1) embed absolute code in relocatable files When the assembler is started in relocatable mode, everything is put into a .o65 relocatable file. All address references generate relocation table entries. If a "*= value" pseudo opcode is encountered, then the assembler switches to absolute mode. The following opcodes don't generate relocation table entries. If a "*=" without a value is read, then the assembler switches back to relocatable mode. The relocation program counter is increased with the length of the absolute part and the absolute code is embedded between the relocatable parts. 3.2) embed relocatable code in absolute files This is dropped - too complicated. Should better be done with some objdump or linker programs or so. 3.2) Header options Before any opcode (after starting in relocatable mode, or after a .reloc opcode), a header option can be set by: .fopt byte1, byte2, ... The header option length is automatically set by the assembler. An example for an file author entry: .fopt 3, "Andre Fachat",0 The 3 is the type byte for the author header option. The last zero ends the name. The assembler can be configured to automatically include an assembler header option into a file header. 3.3) allocation of data segment/zeropage segment address space The assembler switches between the different segments by the means of ".text", ".data", ".bss" and ".zero" pseudo opcodes. After starting in relocatable mode, the assembler is in the text segment. The text segment contains the program code. Data holds the initialized data, while bss and zero segments contain uninitialized data for normal/zeropage address space. Everything that is between one of these segment opcodes and the next segment opcode gets into the corresponding segment, i.e. labels, assembled code etc. The text and data segments are saved in the file, while for the bss and zero segments only the length is saved in the file. The assembler should issue a warning when a direct addressing mode is used without a zero segment address and vice versa for 65816 CPUs. 3.4) referencing data/bss/zeropage addresses One problem with the 6502 is, that it cannot load an address within one step or assembler opcode. So an address is loaded with standard byte opcodes, like "lda # The assembler is now intelligent enough to evaluate such expressions and check for: - no address label : ok, absolute - one address label, only add to label : ok, relocate - difference between two addresses : If addresses in same segment, compute diff and set absolute, otherwise bail - everything else : warning This way there is no change in syntax. Address labels are distinguished by using the "label:" syntax, as opposed to "label = value". Also, if the assembler is capable of doing so, an address label may be defined by "label opcode", i.e. without a colon. 3.5) aligning code The 6502 has the problem that some opcodes (e.g. "JMP ($xxFF)" are broken, if the address given is at some (odd) address. But when loading a relocatable file, one cannot know if an address will be odd or even. Therefore there is a new opcode, .align 2 that aligns the next address at the given address boundary. Valid values are 2, 4, and 256. 4) Clearance This file is surely not the optimum and could be improved. Also the header option "assigned numbers" should be added here. For this reason the author, André Fachat, will function as a clearing point, where problems can be discussed and number can be assigned. Dec. 22, 1996, André Fachat (fachat@physik.tu-chemnitz.de) Appendix A) File examples (to be done with reference assembler) xa-2.3.8/doc/xa-de.log0000600000031500000010000000735006236123732013715 0ustar spectrestaff ******** XASS65 1.0 ******** 15.11.89, Andre Fachat 2-Pass-Assembler fr 65(C)02. von Rockwell. Der erste Pass berechnet die Labels, im zweiten Pass wird assembliert. Es wird eine Block-Struktur untersttzt, d.h. die Pseudo-Opcodes .( und .) verbergen dazwischenliegende Labels vor Zugriffen aus anderen als darberliegenden Blocks. Die Quell-, Object- und Fehlerdateien mssen in der Kommandozeile angegeben werden. ******** XASS 1.0 ******* 1.4.90, Andre Fachat Die Object- und Fehlerdateien werden, falls nicht anders angegeben aus der ersten Quelldatei durch „ndern der Extension ermittelt. Es gibt jetzt einen C-„hnlichen Preprozessor mit define, ifdef, include etc. 'Funktionen' k”nnen keine definiert werden. ******** XA 2.00 ******** Andre Fachat Ab jetzt wird das, was im ersten Pass schon zur Ermittelung der Opcode- L„nge assembliert wurde zwischengespeichert. Das verdoppelt die Geschwindigkeit ann„hernd. Dabei wird alles, was bekannt ist, vertokend, um sp„ter nicht wieder soviel suchen zu mssen. ******** XA 2.02 ******** 23.9.90, Andre Fachat Labels k”nnen mit vorangestelltem '&' eine Blockstufe h”her definiert werden, mit einem '-' werden sie global definiert (Block=0). Bei eingeschalteter Option -c werden Fehler bei CMOS-Befehlen erzeugt. Die Tabellen fr die Token-Erkennung sind vereinfacht und damit schneller gemacht. ******** XA 2.03 ******** 16.6.91, Andre Fachat Jetzt wird automatisch eine Liste mit Labels erzeugt und in einer .LAB-Datei gespeichert. Im Preprozessor gibt es jetzt #if. ******** XA 2.04 ******** 14.7.91, Andre Fachat Die Labeltabelle kann jetzt gr”žer als 32kByte werden. Da ein Eintrag in der Label-Tabelle ohne den eigentlichen Namen 14 Byte betr„gt, sind jetzt mehr als 2340 Labels m”glich. Im Preprozessor sind jetzt auch 'Funktions'definitionen m”glich , also z.B. #define mult(a,b) ((a)*(b)) ******** XA 2.05 ******** 29.7.91, Andre Fachat Fr Labels, Defines und die Opcodes wird die Suche nach Hashcode durchgefhrt. damit werden ca. 350kByte Quelltext fr ein 32kByte EPROM nicht mehr in 18 sondern in ca. 3 Minuten assembliert. ******** XA 2.06 ******** 18.9.91,Andre Fachat Der Preprozessor hat jetzt #ifldef und #iflused, was eigentlich heižt 'if label defined' und 'if label used'. Damit lassen sich Bibliotheks- „hnliche Dateien aufbauen. Die Umstellung auf PureC bringt ihn dazu, 350kByte (s.o.) in 2 Minuten zu assemblieren. Die Vergr”žerung der Datei-Puffer per setvbuf() auf 4kByte bringt auch noch 7 Sekunden. Aužerdem wird am Ende eine Statistik ber verbrauchte Resourcen gedruckt. ******** XA 2.07 ******** 30.9.91, Andre Fachat Jetzt wird Zeit und Datum sowie die verbrauchten Sekunden in der Statistik gezeigt. Die Environment-Variablen XAINPUT und XAOUTPUT werden untersttzt. Falls die Quell- und Include-Dateien nicht gefunden werden, werden die in XAINPUT aufgefhrten Pfade der Reihe nach durchgetestet. Falls XAOUTPUT existiert, wird dieser Pfad als Pfad fr .ERR, .LAB und .OBJ-Dateien benutzt. Nach einem Turbo-C Referenzhandbuch sind alle Systemaufrufe (malloc, fopen etc.) jetzt ANSI-kompatibel. (Der C-Quellcode allerdings ist die Darstellung von Chaos im besten K&R-Stil...) ******** 16.2.92, Andre Fachat #print und #printdef werden unterdrckt, wenn sie in der entsprechenden #if-Strukur sind (war bisher im Gegensatz zu echo und include nicht so) ******** XA 2.07b ******** 5.1.94, Andre Fachat Auf englisch uebersetzt, die Abhaengigkeit des Header-files von stdio.h beseitigt, ebenso die Abhaengigkeit von der integer size. in xah.h gibt es jetzt einen Define DIRCHAR und DIRCSTRING, die das Verzeichnistrennzeichen definieren (DIRCHAR als '/' bzw '\\' und DIRCSTRING als "/" bzw. "\\") ******** XA 2.0.7d ******** 96, Andre Fachat Mehr auf Englisch übersetzt. #undef kann ein define löschen. xa-2.3.8/doc/xa-de.txt0000600000031500000010000003470606236122406013755 0ustar spectrestaff---------------------------------------------------------------------------- XA 2.1.0 65(c)02 Cross-Assembler von Andre Fachat ---------------------------------------------------------------------------- * Block-Struktur (Versteckte Label) * Sehr schnell durch hashing * C-ähnlicher Preprozessor ---------------------------------------------------------------------------- 1. Was ist das überhaupt und Geschichte 2. Aufruf und Features 3. 6502 Assembler 4. Pseudo-Opcodes, Block-Struktur und Gültigkeitsbereich von Labels 5. Preprozessor ---------------------------------------------------------------------------- 1. Was ist das überhaupt und Geschichte ---------------------------------------- Mit dem Cross-Assembler können auf einem Rechner Programme für einen anderen Rechner(typ) erstellt werden. Die Programmdateien müssen dann nur noch auf das Zielsystem übertragen werden. In diesem Fall handelt es sich um einen 6502-Cross-Assembler. Der 6502 ist ein 8-Bit-Prozessor, der ursprünglich von MOS Technologies entwickelt wurde. Er tut seine Dienste u.a. im Apple II, Commodore PET, VC20 und C64 (in abgewandelter Form) und vielen anderen. Inzwischen gibt es ihn in vielen Varianten mit verschiedenen Zusätzen und in verschiedenen Gehäusen. Gemeinsam ist allen der Befehlssatz, der für den Assembler die Grundlage bildet. Die CMOS-Versionen bieten allerdings Erweiterungen des Befehlssatzes. Die Idee zu einem Cross-Assembler entstand, als ich mir einen 6502-Computer selbst baute und der (ebenfalls selbstgeschriebene) Assembler auf dem C64 zu langsam wurde. Nachdem auch noch ein Atari ST bei mir rumstand, war die Idee schnell in die Tat umgesetzt. 2. Aufruf und Features ----------------------- Der Assembler besteht nur aus dem Programm "xa". Der Assembler verarbeitet eine oder mehrere Quelldateien zu einer Objektdatei, die direkt verwendet werden kann. Das Linken entfällt, da der Aufwand zu groß und die Geschwindigkeit hoch genug ist, um die 'Libraries' im Quelltext einzubinden. Ca. 350kByte Quelltext werden in 1 Minute und 50 Sekunden zu einer 32kByte Objektdatei für ein EPROM assembliert (naja, der 8MHz Atari war nicht schnell. Aber dafür ist der Wert ziemlich gut. Mein 486DX4/100 braucht vielleicht 2 Sekunden)! Als Ausgabedateien werden eine Objektdatei, eine Fehlerdatei und eine Labeldatei geschrieben. Der Aufruf lautet: XA Quell1 [Quell2 ...] [-oObject] [-eFehler] [-lLabel] [-C] [-v] [-x] Die Angabe der Objekt-, Fehler- und Labeldatei ist optional, ohne Angabe wird die Endung der ersten Quelldatei auf 'obj', 'err' und 'lab' verändert, wenn "-x" angegeben ist. Ansonsten wird "a.o65" als Ausgabedatei verwendet und keine Fehler- und Labeldatei geschrieben. Die Option -C erzeugt Fehlermeldungen bei CMOS-Befehlen. Im Environment werden die Variablen XAOUTPUT und XAINPUT unterstützt. Falls die Quell- und Include-Dateien nicht gefunden werden, werden die in XAINPUT aufgeführten Pfade der Reihe nach durchgetestet. Falls XAOUTPUT existiert, wird dieser Pfad als Pfad für .err, .lab und .obj-Dateien benutzt. Die Komponenten des Pfades sind mit ',' getrennt. Die Labeldatei enthält hinterher eine Liste aller Labels mit Block-Nummer und Wert in dezimal in der Form: 'Label, 1,-1234' in lesbarem ASCII. Die Fehlerdatei enthält die Version des Assemblers, Datum und Uhrzeit des Assemblerlaufs, die Liste der Fehler, die Ausdrücke, die mit #echo und #print im Preprozessor erzeugt werden und eine Statistik über die benutzten Resourcen (Speicherplatz etc.). Die Objektdatei wird nur durch die Quelldatei bestimmt, es wird kein Code vorgesetzt oder angehängt. Die Quelldatei muß im ASCII-Format vorliegen. 3. 6502 Assembler ------------------ Da dies kein 6502-Assemblerkurs werden soll, nur eine ganz kurze Beschreibung. Unterstützt wird der Code für alle Standard-6502 sowie der Code für die Rockwell 65C02-CPU. Der Prozessor hat drei Register, über die die meisten Operationen laufen. Transferoperationen benötigen deshalb immer einen Load- und einen Store-Befehl. Zusätzlich gibt es das Statusregister und den Stackpointer sowie, natürlich, den Programmzähler. Der Stack liegt immer im Bereich $100 und $1ff (Hexadezimal mit vorangestelltem '$'), weshalb der Stackpointer ein 8-Bit-Register ist. Eine besondere Behandlung durch kürzere Befehle erfährt die Zeropage ($0-$ff), bei deren Adresse das Hi-Byte Null ist. Das Statusregister besitzt folgende Flags: N = Negativ O = Overflow B = Break D = Dezimal I = Interrupt Z = Zeroflag C = Carry Befehle: LDA lade Akkumulator LDX lade X-Register LDY lade Y-Register STA speichere Akkumulator STX speichere X-Register STY speichere Y-Register STZ speichere NULL (*) TAX Kopiere Akku nach X TAY Kopiere Akku nach Y TXA Kopiere X nach Akku TYA Kopiere Y nach Akku TSX Kopiere Stackpointer nach X TXS Kopiere X nach Stackpointer ADC Addiere zu Akku mit Übertrag (Carry) (D) SBC Subtrahiere von Akku mit Carry (D) AND Logisches Und mit Akku ORA Logisches Oder mit Akku EOR Exklusiv-Oder mit Akku BIT Bit-Test: Z=A&M, N=M7, O=M6 ROL Rotiere Links Akku oder Speicher A=A*2+C, C=A7 ROR Rotiere Rechts A=A/2+C*127, C=A0 ASL Arithmetisches Linksschieben A=A*2 LSR Logisches Rechtsschieben A=A/2 INX Erhöhe X-Register um eins INY Y INC Erhöhe Akku oder Speicher um eins DEX Erniedrige X-Register um eins DEY Y DEC Erniedrige Akku oder Speicher um eins CMP Vergleiche mit Akku (Substraktion ohne Akku zu ver„ndern) CPX Vergleiche mit X-Register CPY Vergleiche mit Y-Register BNE Verzweige falls nicht Null BEQ Null BMI Negativ BPL Positiv BVC Overflow Clear BVS Overflow Set BCS Carry Set BCC Carry Clear BRA Verzweige immer (*) JMP Springe an Adresse JSR Springe in Unterroutine, Rcksprungadresse auf dem Stack RTS Return from Subroutine CLC Carry-Flag löschen SEC setzen CLD Dezimal-Flag löschen SED setzen CLI Interrupt freigeben SEI sperren CLV Overflow-Flag löschen PHA Akku auf Stack legen PHX XR (*) PHY YR (*) PHP Status PLA Akku vom Stack holen PLX XR (*) PLY YR (*) PLP Status BRK Löst Interrupt mit gesetztem Break-Flag aus RTI Return from Interrupt NOP No Operation TRB Test und Reset Speicher mit Akku (*) BBR Branch on Bit Reset (*) BBS Branch on Bit Set (*) RMB Reset Memory Bit (*) SMB Set Memory Bit (*) Die mit (*) markierten Befehle sind CMOS-Befehle. Außerdem haben einige der anderen Befehle zusätzliche Addressierungsarten. Die mit (D) markierten Befehle arbeiten im Dezimal-Mode (Dezimal-Flag gesetzt) anders, nämlich im BCD-Mode (eine Ziffer von 0-9 in 4 Bit). Addressierungsarten: -Immediate LDA #$12 -Absolute STA $1234 -Zeropage EOR $10 -Bit,ZP,REL BBR #7,$10,label -Akku ASL -Implied TAX -(Indirect,x) LDA ($10,X) -(Indirect),y STA ($3e),Y -Zeropage,x CMP $12,X -Absolut,x LDY $4356,x -(Absolut,x) jmp (jumptabelle,x) -Absolut,y ORA $2345,y -Relative BNE irgendwohin -(Indirect) jmp (berVektor) -Zeropage,y ldx $12,y -Bit,Zeropage RMB #1,zeropage Bei Adressierungsarten, die in der Zeropage und Absolut existieren, wird, soweit möglich die Zeropage-Adressierung angewendet. Ein vorangestelltes '!' erzwingt absolute Adressierung, auch bei einem Wert kleiner 256. Als Wert oder Adresse können arithmetische Ausdrücke mit Hierarchie und Klammerung verwendet werden. Der Assembler versteht folgende Operanden: 123 -Dezimal $234 -Hexadezimal &123 -Oktal %010110 -Binär * -Programmzähler "A" -ASCII-Code labelx -Label -(lab1+1) -Ausdruck Folgende Operatoren können benutzt werden: + -Addition 9 - -Subtraktion 9 * -Multiplikation 10 / -Integer-Division 10 << -Shift nach links 8 >> -Shift nach rechts 8 >=,=> -größer oder gleich 7 <=,=< -kleiner oder gleich 7 < -kleiner 7 > -größer 7 = -gleich 6 <>,>< -ungleich 6 && -Logisches UND 2 || -Logisches ODER 1 & -Bitweises UND 5 | -Bitweises ODER 3 ^ -Bitweises Exklusiv-Oder 4 Die Operatoren mit der höheren Priorität werden zuerst bearbeitet. Ein gültiger Ausdruck ist dann z.B. LDA base+number*2,x Bei Addressierungsarten, die nicht mit einer Klammer beginnen, darf auch im ersten Ausdruck keine Klammer am Anfang stehen: LDX (1+2)*2,y ; Falsch ! LDX 2*(1+2),y ; Richtig ! Vor einem Ausdruck kann ein unärer Operator stehen: < bildet Lo-Byte des Wertes > bildet Hi-Byte des Wertes LDA # xa 2.1.4 6502 Cross Assembler

XA 2.1.4

65(c)02 Cross Assembler

(c) Andre Fachat

email: fachat@galileo.rhein-neckar.de


  1. what it is
  2. parameters and features
  3. 6502 Assembler
  4. pseudo-opcodes, block structures and where labels are valid
  5. pre-processor
  6. utilities
  • literature

What it is

This Cross-Assembler makes programms for another computer that has a 6502-like CPU. This CPU has been widely used in the famous Apple II, all the Commodore 8-Bit Computers (PET, VC20 and a derivate in the C64) and many others. Some are still used in one-chip microcontrollers, e.g. the Rockwell modem chipset. All these chip share a common set of standard machine language commands, some of them (e.g. the CMOS versions) have additional (software) features.

I had the idea for this assembler when I built my small 6502 System that had place for 32kByte ROM to take the kernel and lots of other programms. (After all, it became a multitasking micro-kernel with file-systems for IBM and Commodore, I can even use the IBM drives as Floppy for my C64 with this computer as controller. Piping and i/o-redirection included, of course) Development on my old C64 began to suck with programms growing. So I decided to do a Cross-Assembler on my new Atari ST.

First versions were very like the old Assembler on the C64, not really using the resources (Reading all files two times completely etc). With files growing the assembler also became more sophisticated. Now hashcodes are used for mnemonics, preprocessor definition and label search (Version >= 2.0.5). The files are only read once, putting the preassembled code into memory (Version >= 2.0), taking it from there on pass 2. Now it makes about 350kByte Source Code to about 30kByte ROM code in less then 2 Minutes on an 8 MHz Atari ST with 2.5 MByte RAM and Harddisk. (Well, the Atari is not fast. On my 486DX4/100 it takes about 2 seconds...) But adding the whole relocation stuff slowed it down again.

Parameters and features

The assembler contains only a single programm called "xa" (for Atari: XA.TTP). It takes one or more Source files into one object file, that can directly be used. But the assembler also has a mode to produce relocatable files, conforming to the 'o65' fileformat (See fileformat.txt).

Call:

xa [options] Source1 [Source2 ...] 
Object: this is the name, the output (object) file gets Error: Here you will find the Error listing. Label: this is the label list

'-C' 		gives error codes when using CMOS-opcodes. Default is not to 
		complain.
'-c'		do not produce o65 executable, but object files that can 
		contain undefined references.
'-v' 		go into verbose mode
'-x' 		old filename behaviour (overrides -o, -e and -l)
'-R' 		do not produce absolute code, but do relocation and all that.
'-o filename'	set output filename
'-e filename'	set errorlog filename
'-l filename'	set labellist filename
'-r'		add crossreference list to labellist output 
		(i.e list of filename/line where label is used)
'-M'		allow ':' to appear in comments after a semicolon (MASM mode)
'-b? adr'	set segment start address for ? = t(ext), d(ata), b(ss) or
		z(ero) segment.
'-A adr'	If the _file_ starts at adr in a ROM, then the text segment
		need not be relocated. That of course only works, if the
		data/bss/zero segments are not occupied by other programs too!
'-G'		omit writing the exported globals to the file.
'-B'		Show lines with '.(' or '.)' pseudo opcodes
'-Llabel'	defines 'label' as absolute, undefined reference
'-DDEF=TEXT'	define a preprocessor replacement
'-Ipath'        additional include path for include files. Is evaluated before
                the XAINPUT environment variable. One path per '-I',
                multiple '-Ipath' allowed.
Omitting the errorfile or labelfile Parameter will cause xa to not write these files. Using '-x' will cause xa to take the name of the first source file and change the extension (on an Atari there is only one, like in DOS) to 'obj', 'err' and 'lab' respectively - if the old behaviour is selected with the '-x' option or the files are defined with "-l" and "-e". If no output file is given, "a.o65" is used.

Environment variables:

You can use the variables XAOUTPUT and XAINPUT to adjust the directory structure. If source or include files are not found, the Path in XAINPUT is being searched for the files. The different paths are separated by a comma (','). XAINPUT gives the directory where the *.obj, *.err and *.lab files are put. If they are not set, there will be no search, respectively the files are saved to the current directory.

The label file is a readable ASCII-file and lists all the labels together with their block-count (see below) and their address. The error file lists the version of the assembler, date and time of the assembler run, all the error messages and the stuff being printed with #echo and #print and last but not least a statistics of used resources.

6502 Assembler

xa supports both the standard 6502 opcodes as well as the CMOS versions (Rockwell 65c02). Not supported are the 6502 undocumented opcodes, they have to be put in by hand (with ".byte" directives).

For an introduction to 6502 Assembler please see elsewhere. A (very) short introduction is given in the german version of this text.

Some Assembler specific details:

When using addressing modes that could be zeropage or absolute, zeropage will be taken if possible. This can be prevented by prefixing the address with a '!'. Then absolute addressing is taken, regardless of the address.

Values or Addresses can be expressed by arithmetik expressions with hierachy and bracket. The following operands are understood:

123       -decimal
$234      -hexadecimal
&123      -octal
%010110   -binary
*         -program counter
"A"       -ASCII-code
labelx    -label
-(lab1+1) -expression
The following operands can be used (third column is priority):

+         -addition                     9
-         -subtraction                  9
*         -multiplication               10
/         -integer-division             10
<<        -shift left                   8
>>        -shift right                  8
>=,=>     -more or equal                7 
<=,=<     -less or equal                7
<         -less                         7
>         -more                         7 
=         -equal                        6
<>,><     -not equal                    6
&&        -logical AND                  2
||        -Logical OR                   1
&         -Bitwise AND                  5
|         -Bitwise OR                   3
^         -Bitwise XOR                  4
Operators with higher priority are evaluated first. Brackets can be used as usual.

Valid expressions are, e.g.:

LDA       base+number*2,x
For Addressing modes that do not start with a bracket, you can even use a bracket at the beginning of an expression. Otherwise try this:

LDX       (1+2)*2,y                ; Wrong!
LDX       2*(1+2),y                ; Right!
Before an expression you can use these unitary operators:

    
<      Gives the low byte of the expression
>      Gives the high byte

LDA  #<adresse
Single Assembler statements are being separated by a ':' (You remember the C64 :-) or a newline. Behind Each statement, separated by a ';' you can write some comments. The next colon or a newline ends the comment and starts a new statement. In MASM compatibility mode ('-M' command line option), then a colon in a comment is ignored, i.e. the comment lasts till the newline.

Pseudo opcodes, Block structures and where Labels are valid

In addition to the 6502 opcodes you have the following Pseudo opcodes:

.byt      value1,value2,value3, ...
.word     value1,value2, ...
.asc      "text1","text2", ...
.dsb      length ,fillbte
.fopt     value1, value2, ...
.text	
.data
.bss
.zero
.align    value
*=
.(
.)

'.byt' and '.asc' are identical and save values to the memory (object file) bytewise. '.word' does the same with words (2 Bytes). '.dsb' fills a block with a given length with the value of fillbyte. If fillbyte is not given, zero is taken.

'*=' changes the programm counter. The programm counter is not saved to the file as no rewind is being done. Just the internal counter is reloaded. If a value is given when the assembler has been started in relocation mode ('-R command line option), the assembler goes into no-relocation mode, i.e assembles everything without creating relocation table entries. For '*=' without a value, the assembler switches back to relocation mode. The absolute code is 'embedded' in the text segment, so the text segment program counter is increased by the length of the absolute code.

'.(' opens a new 'block'. All labels in a block are local, i.e. are only visible from inside the block - including sub-blocks. An error is returned if a label is defined that is already defined 'above'. With '.)' the block is closed. You can have a stack of up to 16 blocks in each other (i.e. 16 times '.(' before the first '.)' will work, 17 not).

'.text', '.data', '.bss', '.zero' switch between the different segments. The text segment is where the code goes in. The data segment is where some initialized data goes in (it's actually like a second text segment). The data segment might be allocated separated from the text segment. The contents of the bss and the zero segment are not saved, just the labels are evaluated. Here goes the uninitialized data stuff. The zero segment allows allocation of zeropage space, bss is normal address space. These opcodes can be used in relative and absolute mode.

'.align' aligns the current segment to a byte boundary given by the value. Allowed values are 2, 4, and 256. When using relative mode, the align value is written to the file header, such that relocation keeps the alignment.

'.fopt' works like ".byte", but saves the bytes as a fileoption (see fileformat.txt). The length is computed automatically, so the first byte in the ".fopt" list of values should be the type. For example, the following line sets the filename for the object file.

.fopt 0, "filename", 0
A label is defined by not being an opcode:

label1 LDA #0              ; assignes the programm counter
label2 =1234               ; explicit definition
label3 label4 label5       ; implicit programm counter
label6 label7 = 3	   ; label6 becomes the program counter, while
			   ; label7 is set to 3
label8:   sta label2	   ; As ':' divides opcodes, this is also
			   ; working
You can use more than one label for definition, except for explicit definition. Labels are case sensitive. If a label is proceeded by a '+', this label is defined global. If a label is proceeded by a '&', this label is defined one level 'up' in the block hierachy, and you can use more than one '&'.

Redefinition of a label is possible by proceeding it with a dash '-'.

-sysmem   +=4  ; here you can use ==, +=, -=, *=, /=, &=, |=
-syszp    =123

Preprocessor

The preprocessor is very close to the one of the language C. So in addition to the ';'-comments you can also use C-like comments in '/*' and '*/'. Comments can be nested.

#include  "filename"     includes a file on exactly this position.
			 if the file is not found, it is searched using 
			 XAINPUT. 

#echo  comment           gives a comment to the error file.

#print expression        prints an expression to the error file (after
			 preprocessing and calculating)

#printdef DEFINED        prints the definition of a preprocessor define to
			 the error file.

#define DEF  text	 defines 'DEF' by 'text'

#ifdef DEF               The source code from here to the following #endif
			 or #else is only assembled if 'DEF' is defined
			 with #define.

#else                    just else... (optionally)

#endif                   ends an #if-construct. This is a must to end #IF* 

#ifndef  DEF             .... if DEF is not defined

#if expression           .... if expression is not zero

#iflused label           .... if a label has already been used

#ifldef label            .... if a label is already defined
#iflused and #ifldef work an labels, not on preprocessor defs! With these commands a kind of library is easily built:

#iflused  label
#ifldef   label
#echo     label already defined, not from library
#else
label     lda #0
          ....
#endif
#endif
You can have up to 15 #if* on stack before the first #endif

You can also use #define with functions, like in C.

#define mult(a,b)   ((a)*(b))
The preprocessor also allows continuation lines. I.e. lines that end with a '\' directly before the newline have the following line concatenated to it.

Utilities

There now are a few utilities that come with the assembler:

file65	: prints some information about an o65 file. Can compute the 
          "-A" parameter for xa, to built the following file in a ROM.
reloc65 : relocates o65 files.
mkrom.sh: example shell (bash) script to show how to use the file65 utility
	  to build a ROM image with several in the ROM runnable programs.
ld65	: a linker for o65 files. The given files are linked together and
	  one o65 executable file is produced. All header options of all files
	  are put in the new file. There must not be any undefined reference
	  left, otherwise the output file is corrupt, because
	  for now, ld65 cannot produce object files. But you get a warning.

Literature

  • "Das Maschinensprachebuch zum Commodore 64"
    Lothar Englisch, Data Becker GmbH
  • "Controller Products Data Book"
    Rockwell International, Semiconductor Products Division
  • "Programmieren in C"
    Kernighan, Ritchie, Hanser Verlag
xa-2.3.8/doc/xa.log0000600000031500000010000002171210546754737013343 0ustar spectrestaffxa-2.1.0 * Rewrite of command line option handling to better look like usual (cc) options. * Removed ^M from all files. * Removed all external declarations to header files, and made all static functions static. | Now compiles almost without warning with 'gcc -W -Wall'. -- André Fachat 31 Oct, 1996 xa-2.1.0a * Introduced concept of code relocation. Now each label being set to the program counter is a 'pointer', that gets an entry in a relocation table. Simple arithmetic operations are allowed. The relocation table is still just printed unsortedly. -- André Fachat 31 Oct, 1996 xa-2.1.0b * Produces some preliminary kind of relocatable file, including header etc. Problems -- relocation table does as if file is assembled for address 0. Need a) a better way to set program counter. b) pseudo opcodes for distinguishing segments. c) a way to temporarily disable relocation. d) a way to include extra headers and options into the file. -- André Fachat 31 Oct, 1996 * Assembler now produces a relocatable file format, as described in the file ``fileformat.txt''. Temporarily disabling relocation is with the ``*=value'' directive, while switching back to relocation mode goes with ``*='' (without value). New pseudo opcodes ``.text'', ``.data'', ``.bss'', ``.zero'' switch between the segments. -- André Fachat 02 Nov, 1996 xa-2.1.0e * There was a bug in the arithmetic routine that had set all pointer to the text segment, if something was added. * There also was a bug in the loader when actually using options. * A new pseudo opcode was added -- ``.fopt''. | Works like ``.byte'', but puts these bytes in a file option. | The length in the file option is automagically set. ``.fopt'' | may appear anywhere in the file, but it should be at the | beginning | (might be mandatory in a later version). -- André Fachat 06 Nov, 1996 xa-2.1.0f * Added a command line switch ``-M'' to ignore colons in a comment after a semicolon. * Without it, a colon separates complete mnemonics, including the semicolon comment. | Well, actually this switch is a ``MASM'' compatibility switch, and will surely be expanded someday, when I get more info on MASM. * Now ``*'' and ``='' can be separated for the definition of the program counter and ``.byte'' is also accepted. This makes it more MASM compatible. ".end" is ignored. Still missing is ``.include''. -- André Fachat 11 Nov, 1996 xa-2.1.0g * Started working on ``official'' o65 fileformat. If there are no undefined labels, and no relocated code is embedded in absolute code, the thing should work. -- André Fachat 21 Dec, 1996 xa-2.1.1 * ``.dsb'' now has an _optional_ parameter ``fillbyte''. * Undefined references are now put into the relocation table (i.e. handled correctly) if the ``-c'' option is given. * The file format conforms to o65 version 1 file format. * Embedding absolute in relocatable code and vice versa is buggy... -- André Fachat 21 Dec, 1996 xa-2.1.1a * Embedding absolute code in relocatable seems to work now. -- André Fachat 21 Dec, 1996 xa-2.1.1e * The option to embed relocatable code in absolute code has been dropped. Therefore the command line options ``-A'' (make it romable), ``-b?'' (set segment start addresses), and ``-G'' (omit exported globals from file) have been added. * Internally, the whole thing has been made dynamic; except for the preprocessor (and the storage between pass1 and pass2), everything uses dynamically allocated tables. m_alloc, which had been introduced long time ago because of the buggy malloc on the Atari ST is gone now! -- André Fachat 22 Dec, 1996 xa-2.1.1f * Added the ``-a'' and ``-A'' options to file65, so that it can now print the start addresses for following files in the ROM when making romable code. * Added shell (bash) script ``mkrom.sh'' that assembles a given list of files and builds a ROMable file. The first two bytes are single linked list pointers, and then comes the file. -- André Fachat 02 Jan, 1997 xa-2.1.1g * Added the file ``reloc65'', to relocate o65 files without reassembling them. * Fixed quite some bugs in xa (segment numbering in the globals list and switched low/high byte relocation entry type in relocation table. Now conforms to documentation, i.e. fileformat.txt) -- André Fachat 03 Jan, 1997 xa-2.1.2 * Added ``ld65'', a simple linker for o65 files. * Another bug in xa fixed now. -- André Fachat 04 Jan, 1997 xa-2.1.3 * Allows to use ``.data'' etc in absolute mode, too. No relocation entries are generated then. Segment start can be set with ``-b?'' command line options, though. Also the data segment is discarded with this method! This allows to use the normal ``.data'' etc syntax even when assembling a ROM (which is done in absolute mode.) * Fixed a bug where ``.dsb'' in a data segment didn't fill with the right value -- André Fachat 25 Mar, 1997 xa-2.1.3e * Added preprocessor continuation lines, and .block and .bend pseudo-opcodes (They map to ``.('' and ``.)'' respectively.) -- André Fachat 27 Jul, 1997 xa-2.1.4 * Do not leave output file around after an error -- this is better for ``make''. * Also it seems to have settled for a while, so I can release a new version. -- André Fachat 11 Sep, 1997 xa-2.1.4c * Fixed a nasty bug that prevented correct relocation table entries when a ``label2=label1'' contruct was used and ``label2'' was accessed. * Added ``-I'' option. -- André Fachat 30 Dec, 1997 xa-2.1.4d * fixed align code. Now inserts NOP opcodes into text segment, and sets file mode appropriately. -- André Fachat 26 Jan, 1998 xa-2.1.4e * Changed o65 fileformat and adopted it in xa. -- André Fachat 26 Jan, 1998 xa-2.1.4g * Fix handling of !zeropageaddress, that was broken (did not result in absolute address, but gave error message.) * Add cross reference list to labels if switched on on command line. * Fix the filename when multiple files are given on the command line (used to give the first filename for all errors in second pass.) -- André Fachat 25 Nov, 1998 xa-2.1.4h * In file65 added support for undefined labels and globals, also for (some known) file options. * Fix a preprocessor bug. -- André Fachat 12 Dec, 1998 xa-2.2.0-p1-1 * Update COPYING to the latest version (Y2K-fixed + new address to GNU) * Lots of fixes to the Makefiles * Cleaned up the structure of the TODO file * Added manual-pages for file65, ld65, printcbm, reloc65, uncpk, and xa * Commented out LIB-flags -lm, -lcurses and -ltermcap, since they are all unused * Added `--help' and `--version' to all binaries * Removed `-h', `-?' and `-v' options where applicable * Created a file containing the version-function; version.h * Moved common macros to a separate file; xad.h * Restructuring of printcbm to become more readable * Added ifndef/define/endif traps to all header-files * Fixed a few typos * Renamed romadr to romaddr * Renamed all functions matching *such* to *search* * Fixed all warnings * Cleaned up all header-files * Reformatted xa.log -- David Weinehall 20 Aug, 2002 xa-2.3.0 * Version number jump for all the unofficial xa's out there * Fixed addressing bugs for @, ! and completed 65816 merge Thanks to David for the report * Moderate legibility overhaul to xat.c (will continue on this) * More compiler warnings corrected Thanks to David for the report * man files completed * Documentation updated * Last line bug corrected (where last line not assembled if no newline) Thanks to silverdr for the report * ld65 is now ldo65 to avoid conflicts with cc65 package * Post-defined labels work better, or at least somewhat (no longer attempts to optimize in pass 2 and generate bad code). Can be forced with ` Thanks to silverdr for the report * Makefile bugs multiplied * @ now mostly obligatory for 24-bit addressing -- Cameron Kaiser 2 Apr, 2006 xa-?? * Introduced switch to convert values in quotes to different character sets. Currently supported are ASCII (default) and PETSCII * Fixed some quote bugs -- André Fachat 23 Dec, 2006 xa-2.3.8/doc/xa.txt0000600000031500000010000003521306627004751013367 0ustar spectrestaff _________________________________________________________________ XA 2.1.4 65(c)02 Cross Assembler (c) Andre Fachat email: fachat@galileo.rhein-neckar.de _________________________________________________________________ 1. what it is 2. parameters and features 3. 6502 Assembler 4. pseudo-opcodes, block structures and where labels are valid 5. pre-processor 6. utilities * literature _________________________________________________________________ What it is This Cross-Assembler makes programms for another computer that has a 6502-like CPU. This CPU has been widely used in the famous Apple II, all the Commodore 8-Bit Computers (PET, VC20 and a derivate in the C64) and many others. Some are still used in one-chip microcontrollers, e.g. the Rockwell modem chipset. All these chip share a common set of standard machine language commands, some of them (e.g. the CMOS versions) have additional (software) features. I had the idea for this assembler when I built my small 6502 System that had place for 32kByte ROM to take the kernel and lots of other programms. (After all, it became a multitasking micro-kernel with file-systems for IBM and Commodore, I can even use the IBM drives as Floppy for my C64 with this computer as controller. Piping and i/o-redirection included, of course) Development on my old C64 began to suck with programms growing. So I decided to do a Cross-Assembler on my new Atari ST. First versions were very like the old Assembler on the C64, not really using the resources (Reading all files two times completely etc). With files growing the assembler also became more sophisticated. Now hashcodes are used for mnemonics, preprocessor definition and label search (Version >= 2.0.5). The files are only read once, putting the preassembled code into memory (Version >= 2.0), taking it from there on pass 2. Now it makes about 350kByte Source Code to about 30kByte ROM code in less then 2 Minutes on an 8 MHz Atari ST with 2.5 MByte RAM and Harddisk. (Well, the Atari is not fast. On my 486DX4/100 it takes about 2 seconds...) But adding the whole relocation stuff slowed it down again. Parameters and features The assembler contains only a single programm called "xa" (for Atari: XA.TTP). It takes one or more Source files into one object file, that can directly be used. But the assembler also has a mode to produce relocatable files, conforming to the 'o65' fileformat (See fileformat.txt). Call: xa [options] Source1 [Source2 ...] Object: this is the name, the output (object) file gets Error: Here you will find the Error listing. Label: this is the label list '-C' gives error codes when using CMOS-opcodes. Default is not to complain. '-c' do not produce o65 executable, but object files that can contain undefined references. '-v' go into verbose mode '-x' old filename behaviour (overrides -o, -e and -l) '-R' do not produce absolute code, but do relocation and all that. '-o filename' set output filename '-e filename' set errorlog filename '-l filename' set labellist filename '-r' add crossreference list to labellist output (i.e list of filename/line where label is used) '-M' allow ':' to appear in comments after a semicolon (MASM mode) '-b? adr' set segment start address for ? = t(ext), d(ata), b(ss) or z(ero) segment. '-A adr' If the _file_ starts at adr in a ROM, then the text segment need not be relocated. That of course only works, if the data/bss/zero segments are not occupied by other programs too! '-G' omit writing the exported globals to the file. '-B' Show lines with '.(' or '.)' pseudo opcodes '-Llabel' defines 'label' as absolute, undefined reference '-DDEF=TEXT' define a preprocessor replacement '-Ipath' additional include path for include files. Is evaluated before the XAINPUT environment variable. One path per '-I', multiple '-Ipath' allowed. Omitting the errorfile or labelfile Parameter will cause xa to not write these files. Using '-x' will cause xa to take the name of the first source file and change the extension (on an Atari there is only one, like in DOS) to 'obj', 'err' and 'lab' respectively - if the old behaviour is selected with the '-x' option or the files are defined with "-l" and "-e". If no output file is given, "a.o65" is used. Environment variables: You can use the variables XAOUTPUT and XAINPUT to adjust the directory structure. If source or include files are not found, the Path in XAINPUT is being searched for the files. The different paths are separated by a comma (','). XAINPUT gives the directory where the *.obj, *.err and *.lab files are put. If they are not set, there will be no search, respectively the files are saved to the current directory. The label file is a readable ASCII-file and lists all the labels together with their block-count (see below) and their address. The error file lists the version of the assembler, date and time of the assembler run, all the error messages and the stuff being printed with #echo and #print and last but not least a statistics of used resources. 6502 Assembler xa supports both the standard 6502 opcodes as well as the CMOS versions (Rockwell 65c02). Not supported are the 6502 undocumented opcodes, they have to be put in by hand (with ".byte" directives). For an introduction to 6502 Assembler please see elsewhere. A (very) short introduction is given in the german version of this text. Some Assembler specific details: When using addressing modes that could be zeropage or absolute, zeropage will be taken if possible. This can be prevented by prefixing the address with a '!'. Then absolute addressing is taken, regardless of the address. Values or Addresses can be expressed by arithmetik expressions with hierachy and bracket. The following operands are understood: 123 -decimal $234 -hexadecimal &123 -octal %010110 -binary * -program counter "A" -ASCII-code labelx -label -(lab1+1) -expression The following operands can be used (third column is priority): + -addition 9 - -subtraction 9 * -multiplication 10 / -integer-division 10 << -shift left 8 >> -shift right 8 >=,=> -more or equal 7 <=,=< -less or equal 7 < -less 7 > -more 7 = -equal 6 <>,>< -not equal 6 && -logical AND 2 || -Logical OR 1 & -Bitwise AND 5 | -Bitwise OR 3 ^ -Bitwise XOR 4 Operators with higher priority are evaluated first. Brackets can be used as usual. Valid expressions are, e.g.: LDA base+number*2,x For Addressing modes that do not start with a bracket, you can even use a bracket at the beginning of an expression. Otherwise try this: LDX (1+2)*2,y ; Wrong! LDX 2*(1+2),y ; Right! Before an expression you can use these unitary operators: < Gives the low byte of the expression > Gives the high byte LDA #a:jsr Txtout:.) #define Aout(a) .(:lda #b:jsr Txtout:jmp c:b .byt a,0:c .) #define Ibout(a) .(:ldx a:lda #0:jsr INTOUT:.) #define Iout(a) .(:ldx a:lda a+1:jsr INTOUT:.) #define PFADLEN 40 #define FN_WR 3 #define FN_RD 4 #define XCODE $f7 #define Version 1 .( .word $0801 *=$0801 .word basicend,10 .byt $9e,"2064",0 ;sys $0810 basicend .word 0 .byt 0,0,0 .( jsr CLRCH jsr iniscreen jsr inipar menu1 Tout(m1atxt) Tout(quellpfad) Tout(m1btxt) Ibout(quelldrv) Tout(m1ctxt) Tout(zielpfad) Tout(m1dtxt) Ibout(zieldrv) Tout(m1etxt) next jsr GET beq next ldx #0 l1 cmp befkeys,x beq exe inx cpx #Anzbefs bcc l1 bcs next exe jsr exec jmp menu1 exec txa asl tax lda madr+1,x pha lda madr,x pha rts madr .word pack-1,unpack-1,quelle-1,ziel-1,switch-1,dir-1,qdrv-1,zdrv-1 befkeys .asc TC_F1,TC_F2,TC_F3,TC_F5,TC_F8,TC_F7,TC_F4,TC_F6 Anzbefs =8 m1atxt .asc TC_LCH,TC_SCO,TC_FF,TC_LF,TC_LF .asc "(F1) PACK PROGRAMMS",TC_CR,TC_LF .asc "(F2) EXTRACT FROM ARCHIVE",TC_CR,TC_LF .asc "(F3) SOURCEPATH/ARC:",0 m1btxt .asc TC_CR,TC_LF .asc "(F4) SOURCEDEVICE:",0 m1ctxt .asc TC_CR,TC_LF .asc "(F5) TARGETPATH/ARC:",0 m1dtxt .asc TC_CR,TC_LF .asc "(F6) TARGETDEVICE :",0 m1etxt .asc TC_CR,TC_LF .asc "(F7) SOURCEDIRECTORY",TC_CR,TC_LF .asc "(F8) EXCHANGE TARGET AND SOURCE",TC_CR,TC_LF .asc "YOUR CHOICE PLEASE",TC_CR,0 .) unpack .( jsr openarcrd bcs cls lda #0 sta rcnt sta rcnt+1 jsr rbyte cmp #Version bne verr loop jsr unpackfile bcc loop Tout(t1) lda rcnt+1 ldx rcnt jsr INTOUT lda #TC_CR jsr BSOUT jsr waitkey cls lda #FN_RD jsr CLOSE rts verr Tout(verrtxt) jmp cls verrtxt .asc "UNKNOWN ARCHIVE VERSION",0 t1 .asc "ARCHIVE HAD BYTES #",0 .) unpackfile .( lda #0 sta wcnt sta wcnt+1 lda #TC_CR jsr BSOUT ldy #0 sty P1 l1 jsr rbyte bcs endx ldy P1 sta filetab,y inc P1 cmp #0 beq endnam jsr BSOUT jmp l1 endnam Tout(ask) jsr waitkey cmp #"J" bne nounpack Tout(tok) lda #<-1 sta P1+1 jsr fxopen jsr Getzst bcs xa bcc lo endx jmp end nounpack Tout(tno) xa lda #0 sta P1+1 lo jsr rbyte bcs cls cmp #XCODE bne xb jsr rbyte sta wxanz cmp #0 clc beq cls jsr rbyte sta wxbyt bit P1+1 bpl lo ly lda wxbyt jsr wbyte dec wxanz bne ly jmp lo xb bit P1+1 bpl lo jsr wbyte jmp lo cls php jsr wbuf lda #FN_WR jsr CLOSE Tout(t1) lda wcnt+1 ldx wcnt jsr INTOUT lda #TC_CR jsr BSOUT plp end rts ask .asc TC_CR,"EXTRACT FILE (Y/N)?",0 t1 .asc "GIVES BYTES #",0 .) incwcnt .( inc wcnt bne l1 inc wcnt+1 l1 rts .) fxopen .( ldy #0 sty INT l1 lda zielpfad,y sta INBUF,y beq l2 iny cmp #":" beq l1a cmp #"/" bne l1b l1a sty INT l1b cpy #PFADLEN bcc l1 l2 ldx INT ldy #0 l3 lda filetab,y sta INBUF,x inx iny cmp #0 bne l3 dex txa ldx #INBUF jsr SETFNPAR lda #FN_WR ldx zieldrv ldy #1 jsr SETFPAR jsr OPEN bcs err jsr clrwrbuf clc err rts .) openarcrd .( ldy #0 l0 lda quellpfad,y beq l1 iny cpy #PFADLEN bcc l0 l1 cpy #0 beq err tya ldx #quellpfad jsr SETFNPAR lda #FN_RD ldx quelldrv ldy #0 jsr SETFPAR jsr OPEN bcs err jsr Getqst bcs err jsr clrrdbuf clc rts err sec rts .) pack .( jsr getlist lda anzfiles beq end jsr openarcwr bcs cls lda #Version jsr wbyte lda #0 sta P1 l1 jsr setfadr sta P2 stx P2+1 jsr packfile inc P1 lda P1 cmp anzfiles bcc l1 jsr wbuf cls lda #FN_WR jsr CLOSE jsr Getzst end jmp LINEIN:rts .) packfile .( Tout(lft) ldy #0 l1 sty P1+1 lda (P2),y jsr BSOUT jsr wbyte ldy P1+1 iny cmp #0 bne l1 jsr fopen bcs le jsr clrwxbyt l2 jsr rbyte bcs l3 jsr wxbyte jmp l2 l3 jsr savwxbyt le lda #FN_RD jsr CLOSE lda #XCODE jsr wbyte lda #0 jsr wbyte lda #TC_CR jsr BSOUT rts lft .asc TC_CR,"cOPYING ",0 .) fopen .( ldy #0 sty INT l1 lda quellpfad,y sta INBUF,y beq l2 iny cmp #":" beq l1a cmp #"/" bne l1b l1a sty INT l1b cpy #PFADLEN bcc l1 l2 ldx INT ldy #0 l3 lda (P2),y sta INBUF,x inx iny cmp #0 bne l3 dex txa ldx #INBUF jsr SETFNPAR lda #FN_RD ldx quelldrv ldy #0 jsr SETFPAR jsr OPEN bcs err jsr clrrdbuf clc err rts .) incrcnt .( inc rcnt bne l1 inc rcnt+1 l1 rts .) rbyte .( ldy ro cpy ri beq leerbuf lda rb,y inc ro clc rts leerbuf lda rf beq ldbuf sec rts ldbuf lda #0 sta ri sta ro ldx #FN_RD jsr CHKIN lda #0 sta STATUS lok jsr BASIN pha lda STATUS beq l0 lda #"L" jsr BSOUT Ibout($90) lda #TC_CR jsr BSOUT l0 pla jsr incrcnt ldy ri sta rb,y iny sty ri iny ;cpy ro beq le lda STATUS beq lok le lda STATUS sta rf jsr CLRCH jmp rbyte .) clrrdbuf .( lda #0 sta ri sta ro sta rf rts .) wxbyte .( ldx wxanz beq add inx bne ad2 pha jsr savwxbyt pla jmp add ad2 cmp wxbyt beq adx pha jsr savwxbyt pla add sta wxbyt adx inc wxanz rts .) clrwxbyt .( lda #0 sta wxanz rts .) savwxbyt .( lda wxanz beq nosav cmp #4 bcs savs lda wxbyt cmp #XCODE beq savs l1 lda wxbyt jsr wbyte dec wxanz bne l1 rts savs lda #XCODE jsr wbyte lda wxanz jsr wbyte lda wxbyt jsr wbyte lda #0 sta wxanz nosav rts .) openarcwr .( ldy #0 l0 lda zielpfad,y beq l1 iny cpy #PFADLEN bcc l0 l1 cpy #0 beq err tya ldx #zielpfad jsr SETFNPAR lda #FN_WR ldx zieldrv ldy #1 jsr SETFPAR jsr OPEN bcs err lda zieldrv jsr Getzst bcs err jsr clrwrbuf clc rts err sec rts .) clrwrbuf .( lda #0 sta wi sta wo rts .) wbyte .( ldy wi sta wb,y iny sty wi iny cpy wo bne nowr pha jsr wbuf pla nowr rts .) wbuf .( ldx #FN_WR jsr CKOUT ldy wo l1 cpy wi beq end lda wb,y jsr BSOUT lda STATUS beq l0 tya pha lda #"W" jsr $e716 lda $90 ora #$40 jsr $e716 lda #TC_CR jsr $e716 pla tay l0 jsr incwcnt iny jmp l1 end lda #0 sta wi sta wo jsr CLRCH rts .) .( &Getqst lda quelldrv jmp Getst &Getzst lda zieldrv &Getst pha jsr CLRCH lda #TC_CR jsr BSOUT pla jsr TALK lda #15+$60 jsr SECTALK lda #0 sta STATUS jsr IECIN pha jsr BSOUT l1 jsr IECIN cmp #0 beq l2 jsr BSOUT lda STATUS beq l1 l2 jsr UNTALK pla cmp #"0" bne err clc rts err sec rts .) /* showlist .( lda #0 sta P1 l1 lda P1 cmp anzfiles bcs le jsr setfadr lda #TC_CR jsr BSOUT lda INT ldy INT+1 jsr Txtout inc P1 jmp l1 le rts .) */ .( l4x jmp l4 &getlist lda #0 sta anzfiles lda #TC_FF jsr BSOUT jsr setdirnam jsr SENDNAM lda DEVADR jsr TALK lda SECADR jsr SECTALK lda #0 sta STATUS ldy #3 l0 sty P1 l1 jsr IECIN sta P1+1 ldy STATUS bne l4x jsr IECIN dec P1 bne l1 ldx P1+1 jsr INTOUT lda #" " jsr BSOUT la jsr IECIN cmp #0 beq l4x cmp #TC_REV bne l3x jmp l3 l3x jsr BSOUT cmp #34 bne la lda anzfiles jsr setfadr sta P2 stx P2+1 ldy #0 lb sty P1 jsr IECIN jsr BSOUT ldy P1 cmp #34 beq lc sta (P2),y iny cpy #17 bcc lb lc lda #"," sta (P2),y iny ld sty P1 jsr IECIN jsr BSOUT ldy P1 cmp #" " beq ld sta P1+1 sta (P2),y iny lda #0 sta (P2),y /* lda #TC_CR jsr BSOUT lda P2+1 ldx P2 jsr INTOUT lda #":" jsr BSOUT lda P2 ldy P2+1 jsr Txtout */ lf tax jsr IECIN jsr BSOUT cmp #" " bne lf cpx #"<" beq lg lda #" " jsr BSOUT lg lda #" " jsr BSOUT lda P1+1 jsr testkeys lh jsr IECIN cmp #0 bne lh beq l2 l3 jsr IECIN ldx STATUS bne l4 tax beq l2 jsr BSOUT jmp l3 l2 lda #TC_CR jsr BSOUT jsr GET beq l5 jsr waitkey l5 ldy #2 beq l4 jmp l0 l4 jsr CLSFIL jmp waitkey .) testkeys .( cmp #"P" beq ok cmp #"S" beq ok rts ok Tout(t1) jsr waitkey cmp #"J" beq ja Tout(tno) rts ja Tout(tok) inc anzfiles rts t1 .asc TC_REV,"YES/NO ",TC_CRL,TC_CRL,TC_CRL .asc TC_CRL,TC_CRL,TC_CRL,TC_CRL,0 &tno .asc TC_REO,"NO ",0 &tok .asc TC_REO,"YES ",0 .) setfadr .( ldx #0 stx INT+1 asl rol INT+1 asl rol INT+1 sta INT ldx INT+1 asl rol INT+1 asl rol INT+1 clc adc INT sta INT txa adc INT+1 sta INT+1 lda #filetab adc INT+1 sta INT+1 tax pla rts .) dir .( lda #TC_FF jsr BSOUT jsr setdirnam jsr SENDNAM lda DEVADR jsr TALK lda SECADR jsr SECTALK lda #0 sta STATUS ldy #3 l0 sty P1 l1 jsr IECIN sta P1+1 ldy STATUS bne l4 jsr IECIN dec P1 bne l1 ldx P1+1 jsr INTOUT lda #" " jsr BSOUT l3 jsr IECIN ldx STATUS bne l4 tax beq l2 jsr BSOUT jmp l3 l2 lda #TC_CR jsr BSOUT jsr GET beq l5 jsr waitkey l5 ldy #2 bne l0 l4 jsr CLSFIL jmp waitkey .) waitkey jsr GET beq waitkey rts setdirnam .( p1 =INT lda #"$" sta INBUF ldx #1 stx p1 ldy #0 l1 lda quellpfad,y beq nodp cmp #":" beq dp iny cpy #PFADLEN bcc l1 nodp lda #":" sta INBUF,x inx dp ldy #0 dp1 lda quellpfad,y sta INBUF,x beq end cmp #":" beq l2a cmp #"/" bne l2 l2a stx p1 l2 inx iny cpy #PFADLEN bcc dp1 end ldx p1 inx lda #"*" sta INBUF,x inx lda #"." sta INBUF,x inx lda #"*" sta INBUF,x inx txa ldx #INBUF jsr SETFNPAR lda #1 ldx quelldrv ldy #0 jmp SETFPAR .) qdrv .( inc quelldrv lda quelldrv cmp #12 bcc ok lda #8 sta quelldrv ok rts .) zdrv .( inc zieldrv lda zieldrv cmp #12 bcc ok lda #8 sta zieldrv ok rts .) quelle .( Tout(quelltxt) jsr LINEIN ldy #0 q1 lda INBUF,y sta quellpfad,y beq end iny cpy #PFADLEN-1 bcc q1 lda #0 sta quellpfad,y end rts quelltxt .asc TC_CR,"PLEASE INPUT NEW SOURCEPATH/ARCHIVE:",TC_CR,0 .) ziel .( Tout(quelltxt) jsr LINEIN ldy #0 q1 lda INBUF,y sta zielpfad,y beq end iny cpy #PFADLEN-1 bcc q1 lda #0 sta zielpfad,y end rts quelltxt .asc TC_CR,"PLEASE INPUT NEW TARGETPATH/ARCHIVE:",TC_CR,0 .) switch .( lda quelldrv ldx zieldrv stx quelldrv sta zieldrv ldx #0 l1 lda quellpfad,x pha lda zielpfad,x sta quellpfad,x pla sta zielpfad,x inx cpx #PFADLEN bcc l1 rts .) inipar .( lda #0 sta quellpfad sta zielpfad lda DEVADR cmp #8 bcc noval cmp #12 bcc ok noval lda #8 ok sta quelldrv sta zieldrv rts .) Txtout .( p =$22 sta p sty p+1 l1 ldy #0 lda (p),y beq le jsr BSOUT inc p bne l1 inc p+1 bne l1 le rts .) iniscreen .( lda #COL_SCHWARZ sta VIC+VIC_EXTCOL sta VIC+VIC_BCKCOL0 lda #TC_HELLGRUEN jsr BSOUT rts .) sysmem =* quelldrv =sysmem zieldrv =sysmem+1 -sysmem +=2 quellpfad =sysmem zielpfad =sysmem+PFADLEN -sysmem +=2*PFADLEN anzfiles =sysmem -sysmem +=1 wi =sysmem wo =sysmem+1 -sysmem +=2 wb =sysmem -sysmem +=256 wxbyt =sysmem wxanz =sysmem+1 -sysmem +=2 ri =sysmem ro =sysmem+1 rf =sysmem+2 -sysmem +=3 rb =sysmem -sysmem +=256 wcnt =sysmem -sysmem +=2 rcnt =sysmem -sysmem +=2 ecnt =sysmem -sysmem +=2 filetab =sysmem ende .) xa-2.3.8/examples/pack_ger.a650000600000031500000010000004721005677330552015364 0ustar spectrestaff #include "c64def.def" #define Tout(a) .(:lda #a:jsr Txtout:.) #define Aout(a) .(:lda #b:jsr Txtout:jmp c:b .byt a,0:c .) #define Ibout(a) .(:ldx a:lda #0:jsr INTOUT:.) #define Iout(a) .(:ldx a:lda a+1:jsr INTOUT:.) #define PFADLEN 40 #define FN_WR 3 #define FN_RD 4 #define XCODE $f7 #define Version 1 .( .word $0801 *=$0801 .word basicend,10 .byt $9e,"2064",0 ;sys $0810 basicend .word 0 .byt 0,0,0 .( jsr CLRCH jsr iniscreen jsr inipar menu1 Tout(m1atxt) Tout(quellpfad) Tout(m1btxt) Ibout(quelldrv) Tout(m1ctxt) Tout(zielpfad) Tout(m1dtxt) Ibout(zieldrv) Tout(m1etxt) next jsr GET beq next ldx #0 l1 cmp befkeys,x beq exe inx cpx #Anzbefs bcc l1 bcs next exe jsr exec jmp menu1 exec txa asl tax lda madr+1,x pha lda madr,x pha rts madr .word pack-1,unpack-1,quelle-1,ziel-1,switch-1,dir-1,qdrv-1,zdrv-1 befkeys .asc TC_F1,TC_F2,TC_F3,TC_F5,TC_F8,TC_F7,TC_F4,TC_F6 Anzbefs =8 m1atxt .asc TC_LCH,TC_SCO,TC_FF,TC_LF,TC_LF .asc "(F1) PROGRAMME ZUSAMMENPACKEN",TC_CR,TC_LF .asc "(F2) ARCHIV AUSPACKEN",TC_CR,TC_LF .asc "(F3) QUELLPFAD:",0 m1btxt .asc TC_CR,TC_LF .asc "(F4) QUELLDEVICE:",0 m1ctxt .asc TC_CR,TC_LF .asc "(F5) ZIELPFAD :",0 m1dtxt .asc TC_CR,TC_LF .asc "(F6) ZIELDEVICE :",0 m1etxt .asc TC_CR,TC_LF .asc "(F7) QUELLDIRECTORY",TC_CR,TC_LF .asc "(F8) QUELLE UND ZIEL TAUSCHEN",TC_CR,TC_LF .asc "IHRE EINGABE BITTE",TC_CR,0 .) unpack .( jsr openarcrd bcs cls lda #0 sta rcnt sta rcnt+1 jsr rbyte cmp #Version bne verr loop jsr unpackfile bcc loop Tout(t1) lda rcnt+1 ldx rcnt jsr INTOUT lda #TC_CR jsr BSOUT jsr waitkey cls lda #FN_RD jsr CLOSE rts verr Tout(verrtxt) jmp cls verrtxt .asc "UNGUELTIGE ARCHIV-VERSION",0 t1 .asc "ARCHIV HATTE BYTES #",0 .) unpackfile .( lda #0 sta wcnt sta wcnt+1 lda #TC_CR jsr BSOUT ldy #0 sty P1 l1 jsr rbyte bcs endx ldy P1 sta filetab,y inc P1 cmp #0 beq endnam jsr BSOUT jmp l1 endnam Tout(ask) jsr waitkey cmp #"J" bne nounpack Tout(tok) lda #<-1 sta P1+1 jsr fxopen jsr Getzst bcs xa bcc lo endx jmp end nounpack Tout(tno) xa lda #0 sta P1+1 lo jsr rbyte bcs cls cmp #XCODE bne xb jsr rbyte sta wxanz cmp #0 clc beq cls jsr rbyte sta wxbyt bit P1+1 bpl lo ly lda wxbyt jsr wbyte dec wxanz bne ly jmp lo xb bit P1+1 bpl lo jsr wbyte jmp lo cls php jsr wbuf lda #FN_WR jsr CLOSE Tout(t1) lda wcnt+1 ldx wcnt jsr INTOUT lda #TC_CR jsr BSOUT plp end rts ask .asc TC_CR,"DATEI AUSPACKEN (J/N)?",0 t1 .asc "ERGIBT BYTES #",0 .) incwcnt .( inc wcnt bne l1 inc wcnt+1 l1 rts .) fxopen .( ldy #0 sty INT l1 lda zielpfad,y sta INBUF,y beq l2 iny cmp #":" beq l1a cmp #"/" bne l1b l1a sty INT l1b cpy #PFADLEN bcc l1 l2 ldx INT ldy #0 l3 lda filetab,y sta INBUF,x inx iny cmp #0 bne l3 dex txa ldx #INBUF jsr SETFNPAR lda #FN_WR ldx zieldrv ldy #1 jsr SETFPAR jsr OPEN bcs err jsr clrwrbuf clc err rts .) openarcrd .( ldy #0 l0 lda quellpfad,y beq l1 iny cpy #PFADLEN bcc l0 l1 cpy #0 beq err tya ldx #quellpfad jsr SETFNPAR lda #FN_RD ldx quelldrv ldy #0 jsr SETFPAR jsr OPEN bcs err jsr Getqst bcs err jsr clrrdbuf clc rts err sec rts .) pack .( jsr getlist lda anzfiles beq end jsr openarcwr bcs cls lda #Version jsr wbyte lda #0 sta P1 l1 jsr setfadr sta P2 stx P2+1 jsr packfile inc P1 lda P1 cmp anzfiles bcc l1 jsr wbuf cls lda #FN_WR jsr CLOSE jsr Getzst end jmp LINEIN:rts .) packfile .( Tout(lft) ldy #0 l1 sty P1+1 lda (P2),y jsr BSOUT jsr wbyte ldy P1+1 iny cmp #0 bne l1 jsr fopen bcs le jsr clrwxbyt l2 jsr rbyte bcs l3 jsr wxbyte jmp l2 l3 jsr savwxbyt le lda #FN_RD jsr CLOSE lda #XCODE jsr wbyte lda #0 jsr wbyte lda #TC_CR jsr BSOUT rts lft .asc TC_CR,"cOPYING ",0 .) fopen .( ldy #0 sty INT l1 lda quellpfad,y sta INBUF,y beq l2 iny cmp #":" beq l1a cmp #"/" bne l1b l1a sty INT l1b cpy #PFADLEN bcc l1 l2 ldx INT ldy #0 l3 lda (P2),y sta INBUF,x inx iny cmp #0 bne l3 dex txa ldx #INBUF jsr SETFNPAR lda #FN_RD ldx quelldrv ldy #0 jsr SETFPAR jsr OPEN bcs err jsr clrrdbuf clc err rts .) incrcnt .( inc rcnt bne l1 inc rcnt+1 l1 rts .) rbyte .( ldy ro cpy ri beq leerbuf lda rb,y inc ro clc rts leerbuf lda rf beq ldbuf sec rts ldbuf lda #0 sta ri sta ro ldx #FN_RD jsr CHKIN lda #0 sta STATUS lok jsr BASIN pha lda STATUS beq l0 lda #"L" jsr BSOUT Ibout($90) lda #TC_CR jsr BSOUT l0 pla jsr incrcnt ldy ri sta rb,y iny sty ri iny ;cpy ro beq le lda STATUS beq lok le lda STATUS sta rf jsr CLRCH jmp rbyte .) clrrdbuf .( lda #0 sta ri sta ro sta rf rts .) wxbyte .( ldx wxanz beq add inx bne ad2 pha jsr savwxbyt pla jmp add ad2 cmp wxbyt beq adx pha jsr savwxbyt pla add sta wxbyt adx inc wxanz rts .) clrwxbyt .( lda #0 sta wxanz rts .) savwxbyt .( lda wxanz beq nosav cmp #4 bcs savs lda wxbyt cmp #XCODE beq savs l1 lda wxbyt jsr wbyte dec wxanz bne l1 rts savs lda #XCODE jsr wbyte lda wxanz jsr wbyte lda wxbyt jsr wbyte lda #0 sta wxanz nosav rts .) openarcwr .( ldy #0 l0 lda zielpfad,y beq l1 iny cpy #PFADLEN bcc l0 l1 cpy #0 beq err tya ldx #zielpfad jsr SETFNPAR lda #FN_WR ldx zieldrv ldy #1 jsr SETFPAR jsr OPEN bcs err lda zieldrv jsr Getzst bcs err jsr clrwrbuf clc rts err sec rts .) clrwrbuf .( lda #0 sta wi sta wo rts .) wbyte .( ldy wi sta wb,y iny sty wi iny cpy wo bne nowr pha jsr wbuf pla nowr rts .) wbuf .( ldx #FN_WR jsr CKOUT ldy wo l1 cpy wi beq end lda wb,y jsr BSOUT lda STATUS beq l0 tya pha lda #"W" jsr $e716 lda $90 ora #$40 jsr $e716 lda #TC_CR jsr $e716 pla tay l0 jsr incwcnt iny jmp l1 end lda #0 sta wi sta wo jsr CLRCH rts .) .( &Getqst lda quelldrv jmp Getst &Getzst lda zieldrv &Getst pha jsr CLRCH lda #TC_CR jsr BSOUT pla jsr TALK lda #15+$60 jsr SECTALK lda #0 sta STATUS jsr IECIN pha jsr BSOUT l1 jsr IECIN cmp #0 beq l2 jsr BSOUT lda STATUS beq l1 l2 jsr UNTALK pla cmp #"0" bne err clc rts err sec rts .) /* showlist .( lda #0 sta P1 l1 lda P1 cmp anzfiles bcs le jsr setfadr lda #TC_CR jsr BSOUT lda INT ldy INT+1 jsr Txtout inc P1 jmp l1 le rts .) */ .( l4x jmp l4 &getlist lda #0 sta anzfiles lda #TC_FF jsr BSOUT jsr setdirnam jsr SENDNAM lda DEVADR jsr TALK lda SECADR jsr SECTALK lda #0 sta STATUS ldy #3 l0 sty P1 l1 jsr IECIN sta P1+1 ldy STATUS bne l4x jsr IECIN dec P1 bne l1 ldx P1+1 jsr INTOUT lda #" " jsr BSOUT la jsr IECIN cmp #0 beq l4x cmp #TC_REV bne l3x jmp l3 l3x jsr BSOUT cmp #34 bne la lda anzfiles jsr setfadr sta P2 stx P2+1 ldy #0 lb sty P1 jsr IECIN jsr BSOUT ldy P1 cmp #34 beq lc sta (P2),y iny cpy #17 bcc lb lc lda #"," sta (P2),y iny ld sty P1 jsr IECIN jsr BSOUT ldy P1 cmp #" " beq ld sta P1+1 sta (P2),y iny lda #0 sta (P2),y /* lda #TC_CR jsr BSOUT lda P2+1 ldx P2 jsr INTOUT lda #":" jsr BSOUT lda P2 ldy P2+1 jsr Txtout */ lf tax jsr IECIN jsr BSOUT cmp #" " bne lf cpx #"<" beq lg lda #" " jsr BSOUT lg lda #" " jsr BSOUT lda P1+1 jsr testkeys lh jsr IECIN cmp #0 bne lh beq l2 l3 jsr IECIN ldx STATUS bne l4 tax beq l2 jsr BSOUT jmp l3 l2 lda #TC_CR jsr BSOUT jsr GET beq l5 jsr waitkey l5 ldy #2 beq l4 jmp l0 l4 jsr CLSFIL jmp waitkey .) testkeys .( cmp #"P" beq ok cmp #"S" beq ok rts ok Tout(t1) jsr waitkey cmp #"J" beq ja Tout(tno) rts ja Tout(tok) inc anzfiles rts t1 .asc TC_REV,"JA/NEIN",TC_CRL,TC_CRL,TC_CRL .asc TC_CRL,TC_CRL,TC_CRL,TC_CRL,0 &tno .asc TC_REO,"NEIN ",0 &tok .asc TC_REO,"JA ",0 .) setfadr .( ldx #0 stx INT+1 asl rol INT+1 asl rol INT+1 sta INT ldx INT+1 asl rol INT+1 asl rol INT+1 clc adc INT sta INT txa adc INT+1 sta INT+1 lda #filetab adc INT+1 sta INT+1 tax pla rts .) dir .( lda #TC_FF jsr BSOUT jsr setdirnam jsr SENDNAM lda DEVADR jsr TALK lda SECADR jsr SECTALK lda #0 sta STATUS ldy #3 l0 sty P1 l1 jsr IECIN sta P1+1 ldy STATUS bne l4 jsr IECIN dec P1 bne l1 ldx P1+1 jsr INTOUT lda #" " jsr BSOUT l3 jsr IECIN ldx STATUS bne l4 tax beq l2 jsr BSOUT jmp l3 l2 lda #TC_CR jsr BSOUT jsr GET beq l5 jsr waitkey l5 ldy #2 bne l0 l4 jsr CLSFIL jmp waitkey .) waitkey jsr GET beq waitkey rts setdirnam .( p1 =INT lda #"$" sta INBUF ldx #1 stx p1 ldy #0 l1 lda quellpfad,y beq nodp cmp #":" beq dp iny cpy #PFADLEN bcc l1 nodp lda #":" sta INBUF,x inx dp ldy #0 dp1 lda quellpfad,y sta INBUF,x beq end cmp #":" beq l2a cmp #"/" bne l2 l2a stx p1 l2 inx iny cpy #PFADLEN bcc dp1 end ldx p1 inx lda #"*" sta INBUF,x inx lda #"." sta INBUF,x inx lda #"*" sta INBUF,x inx txa ldx #INBUF jsr SETFNPAR lda #1 ldx quelldrv ldy #0 jmp SETFPAR .) qdrv .( inc quelldrv lda quelldrv cmp #12 bcc ok lda #8 sta quelldrv ok rts .) zdrv .( inc zieldrv lda zieldrv cmp #12 bcc ok lda #8 sta zieldrv ok rts .) quelle .( Tout(quelltxt) jsr LINEIN ldy #0 q1 lda INBUF,y sta quellpfad,y beq end iny cpy #PFADLEN-1 bcc q1 lda #0 sta quellpfad,y end rts quelltxt .asc TC_CR,"BITTE NEUEN QUELLPFAD EINGEBEN:",TC_CR,0 .) ziel .( Tout(quelltxt) jsr LINEIN ldy #0 q1 lda INBUF,y sta zielpfad,y beq end iny cpy #PFADLEN-1 bcc q1 lda #0 sta zielpfad,y end rts quelltxt .asc TC_CR,"BITTE NEUEN ZIELPFAD EINGEBEN:",TC_CR,0 .) switch .( lda quelldrv ldx zieldrv stx quelldrv sta zieldrv ldx #0 l1 lda quellpfad,x pha lda zielpfad,x sta quellpfad,x pla sta zielpfad,x inx cpx #PFADLEN bcc l1 rts .) inipar .( lda #0 sta quellpfad sta zielpfad lda DEVADR cmp #8 bcc noval cmp #12 bcc ok noval lda #8 ok sta quelldrv sta zieldrv rts .) Txtout .( p =$22 sta p sty p+1 l1 ldy #0 lda (p),y beq le jsr BSOUT inc p bne l1 inc p+1 bne l1 le rts .) iniscreen .( lda #COL_SCHWARZ sta VIC+VIC_EXTCOL sta VIC+VIC_BCKCOL0 lda #TC_HELLGRUEN jsr BSOUT rts .) sysmem =* quelldrv =sysmem zieldrv =sysmem+1 -sysmem +=2 quellpfad =sysmem zielpfad =sysmem+PFADLEN -sysmem +=2*PFADLEN anzfiles =sysmem -sysmem +=1 wi =sysmem wo =sysmem+1 -sysmem +=2 wb =sysmem -sysmem +=256 wxbyt =sysmem wxanz =sysmem+1 -sysmem +=2 ri =sysmem ro =sysmem+1 rf =sysmem+2 -sysmem +=3 rb =sysmem -sysmem +=256 wcnt =sysmem -sysmem +=2 rcnt =sysmem -sysmem +=2 ecnt =sysmem -sysmem +=2 filetab =sysmem ende .) xa-2.3.8/examples/peng.l0000644000031500000010000001046610413276014014377 0ustar spectrestaffbasicend, 0x080b, 1, 0x0000 iniscreen, 0x10c4, 1, 0x0000 inipar, 0x1093, 1, 0x0000 menu1, 0x0819, 2, 0x0000 m1atxt, 0x0897, 2, 0x0000 Txtout, 0x10ae, 1, 0x0000 quellpfad, 0x10d4, 1, 0x0000 m1btxt, 0x08e1, 2, 0x0000 quelldrv, 0x10d2, 1, 0x0000 m1ctxt, 0x08f6, 2, 0x0000 zielpfad, 0x10fc, 1, 0x0000 m1dtxt, 0x090d, 2, 0x0000 zieldrv, 0x10d3, 1, 0x0000 m1etxt, 0x0923, 2, 0x0000 next, 0x085a, 2, 0x0000 l1, 0x0861, 2, 0x0000 befkeys, 0x088f, 2, 0x0000 exe, 0x086d, 2, 0x0000 Anzbefs, 0x0008, 2, 0x0000 exec, 0x0873, 2, 0x0000 madr, 0x087f, 2, 0x0000 pack, 0x0b32, 1, 0x0000 unpack, 0x0970, 1, 0x0000 quelle, 0x0fe5, 1, 0x0000 ziel, 0x102b, 1, 0x0000 switch, 0x1071, 1, 0x0000 dir, 0x0f01, 1, 0x0000 qdrv, 0x0fc5, 1, 0x0000 zdrv, 0x0fd5, 1, 0x0000 openarcrd, 0x0aff, 1, 0x0000 cls, 0x09a1, 12, 0x0000 rcnt, 0x132e, 1, 0x0000 rbyte, 0x0c09, 1, 0x0000 verr, 0x09a7, 12, 0x0000 loop, 0x0984, 12, 0x0000 unpackfile, 0x09dd, 1, 0x0000 t1, 0x09c9, 12, 0x0000 waitkey, 0x0f5f, 1, 0x0000 verrtxt, 0x09b1, 12, 0x0000 wcnt, 0x132c, 1, 0x0000 l1, 0x09ee, 15, 0x0000 endx, 0x0a27, 15, 0x0000 filetab, 0x1332, 1, 0x0000 endnam, 0x0a04, 15, 0x0000 ask, 0x0a8b, 15, 0x0000 nounpack, 0x0a2a, 15, 0x0000 tok, 0x0ec9, 1, 0x0000 fxopen, 0x0ab7, 1, 0x0000 Getzst, 0x0d6a, 1, 0x0000 xa, 0x0a31, 15, 0x0000 lo, 0x0a35, 15, 0x0000 end, 0x0a8a, 15, 0x0000 tno, 0x0ec0, 1, 0x0000 cls, 0x0a6b, 15, 0x0000 xb, 0x0a61, 15, 0x0000 wxanz, 0x1228, 1, 0x0000 wxbyt, 0x1227, 1, 0x0000 ly, 0x0a53, 15, 0x0000 wbyte, 0x0d0f, 1, 0x0000 wbuf, 0x0d25, 1, 0x0000 t1, 0x0aa0, 15, 0x0000 incwcnt, 0x0aae, 1, 0x0000 l1, 0x0ab6, 20, 0x0000 l1, 0x0abb, 21, 0x0000 l2, 0x0ad2, 21, 0x0000 l1a, 0x0acc, 21, 0x0000 l1b, 0x0ace, 21, 0x0000 l3, 0x0ad6, 21, 0x0000 err, 0x0afe, 21, 0x0000 clrwrbuf, 0x0d06, 1, 0x0000 l0, 0x0b01, 22, 0x0000 l1, 0x0b0b, 22, 0x0000 err, 0x0b30, 22, 0x0000 Getqst, 0x0d64, 1, 0x0000 clrrdbuf, 0x0c6a, 1, 0x0000 getlist, 0x0da7, 1, 0x0000 anzfiles, 0x1124, 1, 0x0000 end, 0x0b66, 23, 0x0000 openarcwr, 0x0cd0, 1, 0x0000 cls, 0x0b5e, 23, 0x0000 l1, 0x0b48, 23, 0x0000 setfadr, 0x0ed2, 1, 0x0000 packfile, 0x0b6a, 1, 0x0000 lft, 0x0baf, 24, 0x0000 l1, 0x0b73, 24, 0x0000 fopen, 0x0bb9, 1, 0x0000 le, 0x0b9a, 24, 0x0000 clrwxbyt, 0x0c97, 1, 0x0000 l2, 0x0b8c, 24, 0x0000 l3, 0x0b97, 24, 0x0000 wxbyte, 0x0c76, 1, 0x0000 savwxbyt, 0x0c9d, 1, 0x0000 l1, 0x0bbd, 26, 0x0000 l2, 0x0bd4, 26, 0x0000 l1a, 0x0bce, 26, 0x0000 l1b, 0x0bd0, 26, 0x0000 l3, 0x0bd8, 26, 0x0000 err, 0x0bff, 26, 0x0000 incrcnt, 0x0c00, 1, 0x0000 l1, 0x0c08, 27, 0x0000 ro, 0x122a, 1, 0x0000 ri, 0x1229, 1, 0x0000 leerbuf, 0x0c19, 28, 0x0000 rb, 0x122c, 1, 0x0000 rf, 0x122b, 1, 0x0000 ldbuf, 0x0c20, 28, 0x0000 lok, 0x0c31, 28, 0x0000 l0, 0x0c4a, 28, 0x0000 le, 0x0c5f, 28, 0x0000 add, 0x0c90, 31, 0x0000 ad2, 0x0c86, 31, 0x0000 adx, 0x0c93, 31, 0x0000 nosav, 0x0ccf, 33, 0x0000 savs, 0x0cb9, 33, 0x0000 l1, 0x0cad, 33, 0x0000 l0, 0x0cd2, 34, 0x0000 l1, 0x0cdc, 34, 0x0000 err, 0x0d04, 34, 0x0000 wi, 0x1125, 1, 0x0000 wo, 0x1126, 1, 0x0000 wb, 0x1127, 1, 0x0000 nowr, 0x0d24, 36, 0x0000 l1, 0x0d2d, 37, 0x0000 end, 0x0d58, 37, 0x0000 l0, 0x0d51, 37, 0x0000 Getst, 0x0d6d, 1, 0x0000 l1, 0x0d8a, 38, 0x0000 l2, 0x0d98, 38, 0x0000 err, 0x0da2, 38, 0x0000 l4x, 0x0da4, 39, 0x0000 l4, 0x0e80, 39, 0x0000 setdirnam, 0x0f65, 1, 0x0000 l0, 0x0dc7, 39, 0x0000 l1, 0x0dc9, 39, 0x0000 la, 0x0de3, 39, 0x0000 l3x, 0x0df1, 39, 0x0000 l3, 0x0e5c, 39, 0x0000 lb, 0x0e04, 39, 0x0000 lc, 0x0e19, 39, 0x0000 ld, 0x0e1e, 39, 0x0000 lf, 0x0e35, 39, 0x0000 lg, 0x0e49, 39, 0x0000 testkeys, 0x0e86, 1, 0x0000 lh, 0x0e53, 39, 0x0000 l2, 0x0e6c, 39, 0x0000 l5, 0x0e79, 39, 0x0000 ok, 0x0e8f, 40, 0x0000 t1, 0x0eb0, 40, 0x0000 ja, 0x0ea5, 40, 0x0000 l0, 0x0f1c, 45, 0x0000 l1, 0x0f1e, 45, 0x0000 l4, 0x0f59, 45, 0x0000 l3, 0x0f38, 45, 0x0000 l2, 0x0f48, 45, 0x0000 l5, 0x0f55, 45, 0x0000 p1, 0x0014, 46, 0x0000 l1, 0x0f70, 46, 0x0000 nodp, 0x0f7e, 46, 0x0000 dp, 0x0f84, 46, 0x0000 dp1, 0x0f86, 46, 0x0000 end, 0x0f9e, 46, 0x0000 l2a, 0x0f96, 46, 0x0000 l2, 0x0f98, 46, 0x0000 ok, 0x0fd4, 47, 0x0000 ok, 0x0fe4, 48, 0x0000 quelltxt, 0x1004, 49, 0x0000 q1, 0x0ff1, 49, 0x0000 end, 0x1003, 49, 0x0000 quelltxt, 0x104a, 51, 0x0000 q1, 0x1037, 51, 0x0000 end, 0x1049, 51, 0x0000 l1, 0x107f, 53, 0x0000 noval, 0x10a5, 54, 0x0000 ok, 0x10a7, 54, 0x0000 p, 0x0022, 55, 0x0000 l1, 0x10b2, 55, 0x0000 le, 0x10c3, 55, 0x0000 sysmem, 0x1332, 1, 0x0000 ecnt, 0x1330, 1, 0x0000 ende, 0x10d2, 1, 0x0000 xa-2.3.8/loader/0000700000031500000010000000000006463224255012712 5ustar spectrestaffxa-2.3.8/loader/Makefile0000600000031500000010000000045206263033137014350 0ustar spectrestaff all: loader example test2 rom65 loader: loader.a65 file.def ../xa loader.a65 -o loader clean: rm -f loader test2 example a.o65 rom65 example: test.a ../xa -R test.a -o example test2: test2.a ../xa test2.a -o test2 rom65: test.a ../mkrom.sh -O "-G" -S "-bd 1234" -R rom65 test.a test.a xa-2.3.8/loader/README0000600000031500000010000000036606237225675013607 0ustar spectrestaff In this directory you find two test files, i.e. test.a and test2.a for xa. test.a is assembled into the file "example", which is loaded by the relocator "loader", when started on a C64. Don't try to execute this file, it's just for testing. xa-2.3.8/loader/ex20000600000031500000010000000017606263221167013336 0ustar spectrestaffo65þ{   filename©Э P±l ê­ ­ ©ÿB ‚‚„…‚"Bÿabsvbla{bsslab zerolab xa-2.3.8/loader/example20000600000031500000010000000013206257257131014350 0ustar spectrestaffo65%€@ filename©€Ð­.P±l.€3€ê­@­©.€&€ ‚‚„…"2‚B"&xa-2.3.8/loader/file.def0000600000031500000010000000142306325140753014310 0ustar spectrestaff /* These definitions are without the two leading version/marker bytes, * length is without options */ #define HDR_MAGIC 0 #define HDR_VERSION 3 #define HDR_MODE 4 #define HDR_TBASE 6 #define HDR_TLEN 8 #define HDR_DBASE 10 #define HDR_DLEN 12 #define HDR_BBASE 14 #define HDR_BLEN 16 #define HDR_ZBASE 18 #define HDR_ZLEN 20 #define HDR_STACKLEN 22 #define HDR_LEN 24 #define A_ADR $80 #define A_HIGH $40 /* or'd with the low byte */ #define A_LOW $20 #define A_MASK $e0 /* reloc type mask */ #define A_FMASK $0f /* segment type mask */ #define SEG_UNDEF 0 #define SEG_ABS 1 #define SEG_TEXT 2 #define SEG_DATA 3 #define SEG_BSS 4 #define SEG_ZERO 5 #define FM_OBJ %00010000 #define FM_SIZE %00100000 #define FM_RELOC %01000000 #define FM_CPU %10000000 xa-2.3.8/loader/loader.a650000600000031500000010000003027006257033434014477 0ustar spectrestaff /************************************************************************** * * Loader for 6502 relocatable binary format * * The loader supports 16 bit o65 version 1 files without undefined * references. Also it doesn't like pagewise relocation and 65816 * code, because there are different/additional relocation entries. * * The support routines, that have to be changed are at the end of the * file. The stuff in this file is in absolute format (well, you have to * bootstrap from something :-) * The support routines for the file handling are for the operating system * OS/A65, as of version 1.3.10b. The first part of the file (wrapped in * "#ifdef C64") shows how to use it with a C64, for example. * * The subroutine 'loader' is called with a file descriptor, that has a * meaning for the support routines, in the X register. * The file must already be open. Also binit must have been called before. * The loader doesn't close the file. * * Support routines are: * binit a = hi byte start address memory to handle, * x = hi byte length of memory to handle * balloc a/y = length of block -> x = memory descriptor * bfree x = memory block descriptor to free * getbadr x = memory descriptor -> a/y address of memory block * * zalloc a = length of needed zeropage block. returns a=address * zfree a = address of block to free * * fgetc x = file descriptor, returns read byte (c=0) or error (c=1) * The error is passed through; fgetc blocks if no data * available * fgetb x = filedescriptor, a/y = address of block descriptor, * i.e. a word start address and a word length of block. * returns (c=0) or error in accu (c=1). * **************************************************************************/ /************************************************************************** * This part is a binding for a C64 * to show how it works */ #define C64 #ifdef C64 sysmem =$033c syszp =$57 .word $0801 *=$801 .word nextl .word 10 .byt $9e, "2080",0 nextl .word 0 .dsb 2080-*, 0 c64load .( lda #>PRGEND+255 ldx #>$A000-PRGEND jsr binit ; init memory handling lda #7 ldx #fname jsr $ffbd ; setfnpar lda #2 ldx #11 ldy #0 jsr $ffba ; setfpar jsr $ffc0 ; open bcs end ldx #2 jsr $ffc6 ; chkin bcs end jsr loader ; don't care about x, chkin did it php pha jsr $ffcc ; clrch lda #2 jsr $ffc3 ; close pla plp end rts fname ;.asc "example",0 .byt $45, $58, $41, $4d, $50, $4c, $45, 0 .) fgetc .( jsr $ffcf php pha bcc carry lda #"C" jsr $ffd2 pla pha carry jsr hexout lda #$20 jsr $ffd2 pla plp rts .) hexout .( pha lsr lsr lsr lsr jsr nibout pla nibout and #$0f clc adc #$30 cmp #$3a bcc ok adc #$41-$3a-1 ok jmp $ffd2 .) zalloc .( cmp #$80 ; save from $90 upward = OS, below is only basic bcs end lda #$10 end rts .) zfree .( clc rts .) #endif /************************************************************************** * Here is the real loader code */ #include "file.def" #define E_NOMEM <-40 #define E_FVERSION <-41 loader .( p1 =syszp p2 =syszp+2 -syszp +=4 tmp =sysmem file =sysmem+1 -sysmem +=2 header =sysmem -sysmem +=HDR_LEN textb =sysmem ; memory block ID texta =sysmem+1 ; address of block textl =sysmem+3 ; address of block textd =sysmem+5 ; difference to assemble address -sysmem +=7 datab =sysmem dataa =sysmem+1 datal =sysmem+3 datad =sysmem+5 -sysmem +=7 bssb =sysmem bssa =sysmem+1 bssd =sysmem+3 -sysmem +=5 zeroa =sysmem zerod =sysmem+1 -sysmem +=3 stx file jsr fgetc bcs end sta tmp jsr fgetc bcs end tay lda tmp cpy #0 bne rt cmp #1 beq load rt lda #E_FVERSION ; ok, but not this version end sec rts load .( lda #
header sta p1+1 lda #HDR_LEN sta p1+3 ldx file lda #p1 jsr fgetb bcs end ; header loaded, check magic and version lda header+HDR_MAGIC cmp #$6f bne end lda header+HDR_MAGIC+1 cmp #"6" bne end lda header+HDR_MAGIC+2 cmp #"5" bne end lda header+HDR_VERSION cmp #0 bne end lda header+HDR_MODE+1 and #%11110000 bne end ; now allocate buffers lda header+HDR_TLEN ldy header+HDR_TLEN+1 sta textl sty textl+1 jsr balloc stx textb bcs no_text2 jsr getbadr sta texta sty texta+1 sec sbc header+HDR_TBASE sta textd tya sbc header+HDR_TBASE+1 sta textd+1 lda header+HDR_DLEN ldy header+HDR_DLEN+1 sta datal sty datal+1 jsr balloc stx datab bcs no_data2 no_text2 bcs no_text1 jsr getbadr sta dataa sty dataa+1 sec sbc header+HDR_DBASE sta datad tya sbc header+HDR_DBASE+1 sta datad+1 lda header+HDR_BLEN ldy header+HDR_BLEN+1 jsr balloc stx bssb bcs no_bss no_text1 bcs no_text no_data2 bcs no_data jsr getbadr sta bssa sty bssa+1 sec sbc header+HDR_BBASE sta bssd tya sbc header+HDR_BBASE+1 sta bssd+1 lda header+HDR_ZLEN jsr zalloc bcs no_zero sta zeroa sec sbc header+HDR_ZBASE sta zerod lda #0 sta zerod+1 jmp do_load &no_file lda zeroa jsr zfree no_zero ldx bssb jsr bfree no_bss ldx datab jsr bfree no_data ldx textb jsr bfree no_text rts do_load ; load options (i.e. ignore them now) jsr fgetc bcs no_file cmp #0 beq load_text tay dey optl jsr fgetc bcs no_file dey bne optl beq do_load load_text ; load text segment ldx file lda #texta jsr fgetb bcs no_file ldx file lda #dataa jsr fgetb bcs no_file ; check number of undefined references ldx file jsr fgetc &no_file2 bcs no_file cmp #0 bne no_file ; we have some -> not handled ldx file jsr fgetc bcs no_file cmp #0 bne no_file ; ok, text segments loaded, now relocate lda texta sec sbc #1 sta p1 lda texta+1 sbc #0 sta p1+1 jsr trel lda dataa sec sbc #1 sta p1 lda dataa+1 sbc #0 sta p1+1 jsr trel lda texta ; return start of text segment ldy texta+1 clc rts .) trel .( ldx file jsr fgetc no_file1 bcs no_file2 cmp #0 beq reloc_rts cmp #255 bne t1 lda #254 clc adc p1 sta p1 bcc trel inc p1+1 jmp trel t1 clc adc p1 sta p1 bcc t1a inc p1+1 t1a ; p1 is the relocation address ldx file jsr fgetc bcs no_file1 tay and #A_MASK sta tmp tya and #A_FMASK jsr getreldiff ldy tmp cpy #A_ADR bne t2 ldy #0 clc adc (p1),y sta (p1),y iny txa adc (p1),y sta (p1),y jmp trel t2 cpy #A_LOW bne t3 ldy #0 clc adc (p1),y sta (p1),y jmp trel t3 cpy #A_HIGH bne trel sta p2 stx p2+1 ldx file jsr fgetc clc adc p2 ; just get the carry bit ldy #0 lda p2+1 ; relocate high byte adc (p1),y sta (p1),y jmp trel reloc_rts clc rts .) getreldiff .( ; comparing with SEG_UNDEF would give a way ; to get label value here for undefined refs cmp #SEG_TEXT bne notext lda textd ldx textd+1 rts notext cmp #SEG_DATA bne nodata lda datad ldx datad+1 rts nodata cmp #SEG_BSS bne nobss lda bssd ldx bssd+1 rts nobss cmp #SEG_ZERO bne nozero lda zerod ldx zerod+1 nozero rts .) .) /************************************************************************** * Here come the support routines * * first is a simple and basic implementation of fgetb, just using fgetc */ fgetb .( p =syszp -syszp +=2 file =sysmem l =sysmem+1 -sysmem +=3 stx file ; x=file, a=zp-adr of address, y=zp-adr of len sta p sty p+1 ldy #3 lda (p),y sta l+1 dey lda (p),y sta l dey lda (p),y pha dey lda (p),y sta p pla sta p+1 loop ldx file jsr fgetc ; this is a simple implementation bcs end ldy #0 sta (p),y inc p bne l0 inc p+1 l0 lda l bne l1 dec l+1 l1 dec l lda l ora l+1 bne loop clc end rts .) /************************************************************************** * support for memory allocation * * These routines are taken from a preliminary SLIP implementation, as of * OS/A65 version 1.3.10b */ #define MAXSLOT 8 /**********************************************************************/ /* New memory management for IP buffers */ /* exports */ /* binit */ /* balloc, bfree, btrunc, bsplit, brealloc */ /* getbadr, getblen */ #define MINBUF 8 #define MINMASK %11111000 .( slotladr =sysmem slothadr =sysmem+MAXSLOT slotllen =sysmem+MAXSLOT*2 slothlen =sysmem+MAXSLOT*3 -sysmem +=MAXSLOT*4 flist =sysmem slot =sysmem+2 -sysmem +=3 p =syszp p2 =syszp+2 p3 =syszp+4 p4 =syszp+6 -syszp +=8 /* init memory management */ &binit .( sta p+1 ; hi byte startadress buffer stx p2+1 ; hi byte length of buffer lda #0 tay l0 sta slotladr,y sta slothadr,y iny cpy #MAXSLOT bcc l0 sta p tay sta (p),y iny sta (p),y iny sta (p),y iny lda p2+1 sta (p),y lda p sta flist lda p+1 sta flist+1 clc rts .) /* a/y = size of buffer to be allocated -> x buffer-ID */ &balloc .( /* walk along freelist, and take first matching buffer length is made a multiple of 8 (for freelist connectors */ pha jsr getbslot pla bcc gotslot lda #E_NOMEM rts gotslot stx slot adc #MINBUF-1 and #MINMASK sta slotllen,x tya adc #0 sta slothlen,x lda #0 sta p2 sta p2+1 lda flist sta p lda flist+1 sta p+1 l0 ldy #2 lda (p),y sec sbc slotllen,x sta p3 iny lda (p),y sbc slothlen,x sta p3+1 bcs found lda p sta p2 lda p+1 sta p2+1 ldy #1 lda (p2),y sta p+1 dey lda (p2),y sta p ora p+1 bne l0 oops lda #E_NOMEM sec rts found /* ok, we found a free buffer: p points to the buffer, p2 to the previous one. p3 is the length of the free buffer minus the needed size. If the buffer is longer than needed, create a new free buffer, then link new buffer to freelist */ lda p /* save buffer address */ sta slotladr,x lda p+1 sta slothadr,x lda p3 /* check length */ ora p3+1 beq nocreate lda p /* get address of new free buffer */ clc adc slotllen,x sta p4 lda p+1 adc slothlen,x sta p4+1 ldy #0 /* copy next pointer */ lda (p),y sta (p4),y iny lda (p),y sta (p4),y iny /* set new length */ lda slotllen,x sta (p),y lda p3 sta (p4),y iny lda slothlen,x sta (p),y lda p3+1 sta (p4),y lda p4 sta p lda p4+1 sta p+1 nocreate lda p2 ora p2+1 beq freestart ldy #0 lda p sta (p2),y iny lda p+1 sta (p2),y clc bcc geta freestart lda p sta flist lda p+1 sta flist+1 clc geta lda slotladr,x ldy slothadr,x rts .) /* free buffer (ID=xr) */ &bfree .( lda slothadr,x sta p3+1 lda slotladr,x sta p3 ora p3+1 beq end2 ldy #2 lda slotllen,x sta (p3),y iny lda slothlen,x sta (p3),y lda #0 sta slothadr,x sta slotladr,x lda flist ora flist+1 bne ok /* no free buffer so far? */ lda p3 sta flist lda p3+1 sta flist+1 ldy #0 tya sta (p3),y iny sta (p3),y end2 clc rts ok lda #0 sta p2 sta p2+1 lda flist sta p lda flist+1 sta p+1 /* we have to find the place where to put the buffer in the ordered free list. Then we have to check if we can merge free buffers */ loop lda p3+1 cmp p+1 bcc found bne next lda p3 cmp p bcc found next lda p sta p2 lda p+1 sta p2+1 ldy #0 lda (p2),y sta p iny lda (p2),y sta p+1 ora p bne loop beq found end clc rts found /* p2 is the buffer before the one to be freed, p the one behind. p3 is the buffer to be inserted */ lda p2 ora p2+1 bne fok ; insert before the first free buffer so far ldy #0 lda flist sta (p3),y iny lda flist+1 sta (p3),y lda p3 sta flist ldy p3+1 sty flist+1 jsr bmerge clc rts fok ; insert to list ldy #1 lda p+1 ;lda (p2),y sta (p3),y dey lda p ;lda (p2),y sta (p3),y lda p3 sta (p2),y iny lda p3+1 sta (p2),y lda p3 ldy p3+1 jsr bmerge lda p2 ldy p2+1 jsr bmerge clc rts .) /* get adress of buffer */ &getbadr .( lda slotladr,x ldy slothadr,x clc rts .) /* get length of buffer */ &getblen .( lda slotllen,x ldy slothlen,x clc rts .) /* get free buffer-ID slot */ getbslot .( ldx #0 l0 clc lda slotladr,x ora slothadr,x beq found inx cpx #MAXSLOT bcc l0 found rts .) /* check if two buffers (i.e. a/y plus following) can be merged */ bmerge .( sta p sty p+1 ldy #2 clc lda (p),y adc p sta p3 iny lda (p),y adc p+1 sta p3+1 ldy #0 lda (p),y cmp p3 bne nomerge iny lda (p),y cmp p3+1 bne nomerge merge ldy #2 clc lda (p3),y adc (p),y sta (p),y iny lda (p3),y adc (p),y sta (p),y ldy #0 lda (p3),y sta (p),y iny lda (p3),y sta (p),y nomerge clc rts .) .) PRGEND xa-2.3.8/loader/test.a0000600000031500000010000000047606257255663014054 0ustar spectrestaff .fopt 1, "filename" .( .text &absv = 4 lda #>test+4 bne test *=$8000 ;* lda test-8 .) .text nop ; .fopt 1, "filename" lda bsslab lda zerolab lda #absv*2 .bss bsslab .dsb 20,1 .zero zerolab .dsb 20 xa-2.3.8/loader/test2.a0000600000031500000010000000035606257036461014124 0ustar spectrestaff *=$8000 .( ; .text lda #>test+4 bne test ;*=* lda test-1 .) ; .text nop lda bsslab lda zerolab ; .bss bsslab .dsb 20,1 ; .zero zerolab .dsb 20 xa-2.3.8/loader/test3.a0000600000031500000010000000002206257077211014111 0ustar spectrestaff lda #label lab2 xa-2.3.8/man/0000755000031500000010000000000010546755074012236 5ustar spectrestaffxa-2.3.8/man/README0000644000031500000010000000013210411432720013067 0ustar spectrestaffAlso look at ../doc/ for previous documentation files and the Change log. Cameron Kaiser xa-2.3.8/man/file65.10000644000031500000010000000226110417234046013377 0ustar spectrestaff.TH FILE65 "1" "11 April 2006" .SH NAME file65 \- print information for o65 object files .SH SYNOPSIS .B file65 [\fIOPTION\fR]... \fIFILE\fR... .SH DESCRIPTION .B file65 prints file information for files in the o65 object format. .SH OPTIONS .TP .B \-V Print undefined and global labels. .TP .B \-P Print the segment end addresses (suitable for the .BR xa (1) command line parameter .BR \-b ). .TP .B \-a offset Print .BR xa (1) "ROMmable" parameter for another file behind this one in the same ROM, located at the specified offset. .TP .B \-A offset Does the same thing as .B \-a but only prints the starting address of the next file in the ROM. .TP .B \-\-help Show summary of options. .TP .B \-\-version Show version of program. .SH "SEE ALSO" .BR ldo65 (1), .BR printcbm (1), .BR reloc65 (1), .BR uncpk (1), .BR xa (1), .BR dxa (1) .SH AUTHOR This manual page was written by David Weinehall and Cameron Kaiser . Original xa package (C)1989-1997 Andre Fachat. Additional changes (C)1989-2006 Andre Fachat, Jolse Maginnis, David Weinehall and Cameron Kaiser. The current maintainer is Cameron Kaiser. .SH WEBSITE http://www.floodgap.com/retrotech/xa/ xa-2.3.8/man/ldo65.10000644000031500000010000000222710417234053013236 0ustar spectrestaff.TH LDO65 "1" "11 April 2006" .SH NAME ldo65 \- linker for o65 object files .SH SYNOPSIS .B ldo65 [\fIOPTION\fR]... \fIFILE\fR... .SH DESCRIPTION .B ldo65 is a linker for files in the `o65' object format, formerly .B ld65 but renamed to avoid conflicts with the .B cc65 package (a separate product). .SH OPTIONS .TP .B \-b? addr Relocate segment .B ? to .BR addr \&. .B ? must be either t, d, b or z to indicate the text, data, bss or zero segment respectively. See the .BR xa (1) man page for an explanation. .TP .B \-o filename Set output filename. The default is .BR a.o65 \&. .TP .B \-G Suppress writing of globals. .TP .B \-\-help Show summary of options. .TP .B \-\-version Show version of program. .SH "SEE ALSO" .BR file65 (1), .BR printcbm (1), .BR reloc65 (1), .BR uncpk (1), .BR dxa (1), .BR xa (1) .SH AUTHOR This manual page was written by David Weinehall and Cameron Kaiser . Original xa package (C)1989-1997 Andre Fachat. Additional changes (C)1989-2006 Andre Fachat, Jolse Maginnis, David Weinehall and Cameron Kaiser. The current maintainer is Cameron Kaiser. .SH WEBSITE http://www.floodgap.com/retrotech/xa/ xa-2.3.8/man/printcbm.10000644000031500000010000000132410417234060014116 0ustar spectrestaff.TH PRINTCBM "1" "11 April 2006" .SH NAME printcbm \- list a Commodore BASIC file .SH SYNOPSIS .B printcbm \fIFILE\fR .SH DESCRIPTION .B printcbm lists all lines of the specified Commodore BASIC program. .SH OPTIONS .TP .B \-\-help Show summary of options. .TP .B \-\-version Show version of program. .SH "SEE ALSO" .BR file65 (1), .BR ldo65 (1), .BR reloc65 (1), .BR uncpk (1), .BR dxa (1), .BR xa (1) .SH AUTHOR This manual page was written by David Weinehall . Original xa package (C)1989-1997 Andre Fachat. Additional changes (C)1989-2006 Andre Fachat, Jolse Maginnis, David Weinehall and Cameron Kaiser. The current maintainer is Cameron Kaiser. .SH WEBSITE http://www.floodgap.com/retrotech/xa/ xa-2.3.8/man/reloc65.10000644000031500000010000000263710546755074013607 0ustar spectrestaff.TH RELOC65 "1" "11 April 2006" .SH NAME reloc65 \- relocator for o65 object files .SH SYNOPSIS .B reloc65 [\fIOPTION\fR]... \fIFILE\fR... .SH DESCRIPTION .B reloc65 is a relocator for files in the .B o65 object format. .SH OPTIONS .TP .B \-o filename Set output filename. The default is .BR a.o65 \&. .TP .B \-b? addr Relocate segment .B ? to .BR addr \&. .B ? should be t, d, b or z to represent the text, data, bss or zero segment respectively. See the .BR xa (1) man page for an explanation. .TP .B \-x? Extract segment .B ? from the file instead of writing back the whole file. Valid arguments are t and d for the text or data segment respectively. Not valid for bss or zero. .TP .B \-X Extract text and data segment together from the file instead of writing back the whole file. Relocating data segment to the end of the text segment (ignoring the \-xd option) before extracting. .TP .B \-\-help Show summary of options. .TP .B \-\-version Show version of program. .SH "SEE ALSO" .BR file65 (1), .BR ldo65 (1), .BR printcbm (1), .BR uncpk (1), .BR dxa (1), .BR xa (1) .SH AUTHOR This manual page was written by David Weinehall and Cameron Kaiser . Original xa package (C)1989-1997 Andre Fachat. Additional changes (C)1989-2006 Andre Fachat, Jolse Maginnis, David Weinehall and Cameron Kaiser. The current maintainer is Cameron Kaiser. .SH WEBSITE http://www.floodgap.com/retrotech/xa/ xa-2.3.8/man/uncpk.10000644000031500000010000000236510417234075013434 0ustar spectrestaff.TH UNCPK "1" "11 April 2006" .SH NAME uncpk \- manage c64 cpk archives .SH SYNOPSIS .B uncpk [\fIOPTION\fR]... \fIFILE\fR... .SH DESCRIPTION .B uncpk is an archive tool for Commodore 64 .cpk-format archives. .SH OPTIONS .TP .B c Create an archive. .TP .B x Extract from an archive. .TP .B l List contents of archive. .TP .B a Add a file to the archive. .TP .B v Verbose output. .TP .B \-\-help Show summary of options. .TP .B \-\-version Show version of program. .SH EXAMPLES .TP .B uncpk c foo.cpk bar Create archive .B foo.cpk with the single file .B bar inside it. .TP .B uncpk a foo.cpk bar Add file .B bar to archive .B foo.cpk (which must already exist). .TP .B uncpk x foo.cpk Extract all files from archive .BR foo.cpk \&. .TP .B uncpk l foo.cpk List contents of archive .BR foo.cpk \&. .SH "SEE ALSO" .BR file65 (1), .BR ldo65 (1), .BR printcbm (1), .BR reloc65 (1), .BR dxa (1), .BR xa (1) .SH AUTHOR This manual page was written by David Weinehall and Cameron Kaiser . Original xa package (C)1989-1997 Andre Fachat. Additional changes (C)1989-2006 Andre Fachat, Jolse Maginnis, David Weinehall and Cameron Kaiser. The current maintainer is Cameron Kaiser. .SH WEBSITE http://www.floodgap.com/retrotech/xa/ xa-2.3.8/man/xa.10000644000031500000010000005336613125355422012732 0ustar spectrestaff.TH XA "1" "29 June 2017" .SH NAME xa \- 6502/R65C02/65816 cross-assembler .SH SYNOPSIS .B xa [\fIOPTION\fR]... \fIFILE\fR .SH DESCRIPTION .B xa is a multi-pass cross-assembler for the 8-bit processors in the 6502 series (such as the 6502, 65C02, 6504, 6507, 6510, 7501, 8500, 8501 and 8502), the Rockwell R65C02, and the 16-bit 65816 processor. For a description of syntax, see .B ASSEMBLER SYNTAX further in this manual page. .SH OPTIONS .TP .B \-v Verbose output. .TP .B \-x Use old filename behaviour (overrides .BR \-o , .B \-e and .BR \-l ). This option is now deprecated. .TP .B \-C No CMOS opcodes (default is to allow R65C02 opcodes) .TP .B \-W No 65816 opcodes (default). .TP .B \-w Allow 65816 opcodes. .TP .B \-B Show lines with block open/close (see .BR PSEUDO-OPS ). .TP .B \-c Produce o65 object files instead of executable files (no linking performed); files may contain undefined references. .TP .B \-o filename Set output filename. The default is .BR a.o65 ; use the special filename .BR \- to output to standard output. .TP .B \-e filename Set errorlog filename, default is none. .TP .B \-l filename Set labellist filename, default is none. This is the symbol table and can be used by disassemblers such as .BR dxa (1) to reconstruct source. .TP .B \-r Add cross-reference list to labellist (requires .BR \-l ). .TP .B \-M Allow colons to appear in comments; for MASM compatibility. This does not affect colon interpretation elsewhere. .TP .B \-R Start assembler in relocating mode. .TP .B \-Llabel Defines .B label as an absolute (but undefined) label even when linking. .TP .B \-b? addr Set segment base for segment .B ? to address .BR addr \&. .B ? should be t, d, b or z for text, data, bss or zero segments, respectively. .TP .B \-A addr Make text segment start at an address such that when the file starts at address .BR addr , relocation is not necessary. Overrides .BR \-bt ; other segments still have to be taken care of with .BR \-b \&. .TP .B \-G Suppress list of exported globals. .TP .B \-DDEF=TEXT Define a preprocessor macro on the command line (see .BR PREPROCESSOR ). .TP .B \-I dir Add directory .B dir to the include path (before .BR XAINPUT ; see .BR ENVIRONMENT ). .TP .B \-O charset Define the output charset for character strings. Currently supported are ASCII (default), PETSCII (Commodore ASCII), PETSCREEN (Commodore screen codes) and HIGH (set high bit on all characters). .TP .B \-p? Set the alternative preprocessor character to .BR ? . This is useful when you wish to use .BR cpp (1) and the built-in preprocessor at the same time (see .BR PREPROCESSOR ). Characters may need to be quoted for your shell (example: .B \-p'~' ). .TP .B \-\-help Show summary of options. .TP .B \-\-version Show version of program. .SH ASSEMBLER SYNTAX An introduction to 6502 assembly language programming and mnemonics is beyond the scope of this manual page. We invite you to investigate any number of the excellent books on the subject; one useful title is "Machine Language For Beginners" by Richard Mansfield (COMPUTE!), covering the Atari, Commodore and Apple 8-bit systems, and is widely available on the used market. .LP .B xa supports both the standard NMOS 6502 opcodes as well as the Rockwell CMOS opcodes used in the 65C02 (R65C02). With the .B \-w option, .B xa will also accept opcodes for the 65816. NMOS 6502 undocumented opcodes are intentionally not supported, and should be entered manually using the .B \.byte pseudo-op (see .BR PSEUDO-OPS ). Due to conflicts between the R65C02 and 65816 instruction sets and undocumented instructions on the NMOS 6502, their use is discouraged. .LP In general, .B xa accepts the more-or-less standard 6502 assembler format as popularised by MASM and TurboAssembler. Values and addresses can be expressed either as literals, or as expressions; to wit, .TP 10 .B 123 decimal value .TP .B $234 hexadecimal value .TP .B &123 octal .TP .B %010110 binary .TP .B * current value of the program counter .LP The ASCII value of any quoted character is inserted directly into the program text (example: .B """A""" inserts the byte "A" into the output stream); see also the .B PSEUDO-OPS section. This is affected by the currently selected character set, if any. .LP .B Labels define locations within the program text, just as in other multi-pass assemblers. A label is defined by anything that is not an opcode; for example, a line such as .IP .B label1 lda #0 .LP defines .B label1 to be the current location of the program counter (thus the address of the .B LDA opcode). A label can be explicitly defined by assigning it the value of an expression, such as .IP .B label2 = $d000 .LP which defines .B label2 to be the address $d000, namely, the start of the VIC-II register block on Commodore 64 computers. The program counter .B * is considered to be a special kind of label, and can be assigned to with statements such as .IP .B * = $c000 .LP which sets the program counter to decimal location 49152. With the exception of the program counter, labels cannot be assigned multiple times. To explicitly declare redefinition of a label, place a - (dash) before it, e.g., .IP .B \-label2 = $d020 .LP which sets .B label2 to the Commodore 64 border colour register. The scope of a label is affected by the block it resides within (see .B PSEUDO-OPS for block instructions). A label may also be hard-specified with the .B \-L command line option. .LP For those instructions where the accumulator is the implied argument (such as .B asl and .BR lsr ; .B inc and .B dec on R65C02; etc.), the idiom of explicitly specifying the accumulator with .B a is unnecessary as the proper form will be selected if there is no explicit argument. In fact, for consistency with label handing, if there is a label named .BR a , this will actually generate code referencing that label as a memory location and not the accumulator. Otherwise, the assembler will complain. .LP Labels and opcodes may take .B expressions as their arguments to allow computed values, and may themselves reference other labels and/or the program counter. An expression such as .B lab1+1 (which operates on the current value of label .B lab1 and increments it by one) may use the following operands, given from highest to lowest priority: .TP 8 .B * multiplication (priority 10) .TP .B / integer division (priority 10) .TP .B + addition (priority 9) .TP .B \- subtraction (9) .TP .B << shift left (8) .TP .B >> shift right (8) .TP .B >= => greater than or equal to (7) .TP .B < greater than (7) .TP .B <= =< less than or equal to (7) .TP .B < less than (7) .TP .B = equal to (6) .TP .B <> >< does not equal (6) .TP .B & bitwise AND (5) .TP .B ^ bitwise XOR (4) .TP .B | bitwise OR (3) .TP .B && logical AND (2) .TP .B || logical OR (1) .LP Parentheses are valid. When redefining a label, combining arithmetic or bitwise operators with the = (equals) operator such as .B += and so on are valid, e.g., .IP .B \-redeflabel += (label12/4) .LP Normally, .B xa attempts to ascertain the value of the operand and (when referring to a memory location) use zero page, 16-bit or (for 65816) 24-bit addressing where appropriate and where supported by the particular opcode. This generates smaller and faster code, and is almost always preferable. .LP Nevertheless, you can use these prefix operators to force a particular rendering of the operand. Those that generate an eight bit result can also be used in 8-bit addressing modes, such as immediate and zero page. .TP .B < low byte of expression, e.g., .B lda # high byte of expression .TP .B ! in situations where the expression could be understood as either an absolute or zero page value, do not attempt to optimize to a zero page argument for those opcodes that support it (i.e., keep as 16 bit word) .TP .B @ render as 24-bit quantity for 65816 (must specify .B \-w command-line option). .B This is required to specify any .B 24-bit quantity! .TP .B ` force further optimization, even if the length of the instruction cannot be reliably determined (see .BR NOTES'N'BUGS ) .LP Expressions can occur as arguments to opcodes or within the preprocessor (see .B PREPROCESSOR for syntax). For example, .IP .B lda label2+1 .LP takes the value at .B label2+1 (using our previous label's value, this would be $d021), and will be assembled as .B $ad $21 $d0 to disk. Similarly, .IP .B lda # test.xa .br .B xa test.xa .LP No special arguments need to be passed to .BR xa ; the presence of .BR cpp (1) output is detected automatically. .LP Note that passing your file through .BR cpp (1) may interfere with .BR xa 's own preprocessor directives. In this case, to mask directives from .BR cpp (1), use the .B \-p option to specify an alternative character instead of .BR # , such as the tilde (e.g., .B \-p'~' ). With this option and argument specified, then instead of .BR #include , for example, you can also use .BR ~include , in addition to .B #include (which will also still be accepted by the .B xa preprocessor, assuming any survive .BR cpp (1)). Any character can be used, although frankly pathologic choices may lead to amusing and frustrating glitches during parsing. You can also use this option to defer preprocessor directives that .BR cpp (1) may interpret too early until the file actually gets to .B xa itself for processing. .LP The following preprocessor directives are supported. .TP .B #include """filename""" Inserts the contents of file .B filename at this position. If the file is not found, it is searched using paths specified by the .B \-I command line option or the environment variable .B XAINPUT (q.v.). When inserted, the file will also be parsed for preprocessor directives. .TP .B #echo comment Inserts comment .B comment into the errorlog file, specified with the .B \-e command line option. .TP .B #print expression Computes the value of expression .B expression and prints it into the errorlog file. .TP .B #define DEFINE text Equates macro .B DEFINE with text .B text such that wherever .B DEFINE appears in the assembly source, .B text is substituted in its place (just like .BR cpp (1) would do). In addition, .B #define can specify macro functions like .BR cpp (1) such that a directive like .B #define mult(a,b) ((a)*(b)) would generate the expected result wherever an expression of the form .B mult(a,b) appears in the source. This can also be specified on the command line with the .B \-D option. The arguments of a macro function may be recursively evaluated, unlike other .BR #define s; the preprocessor will attempt to re-evaluate any argument refencing another preprocessor definition up to ten times before complaining. .LP The following directives are conditionals. If the conditional is not satisfied, then the source code between the directive and its terminating .B #endif are expunged and not assembled. Up to fifteen levels of nesting are supported. .TP .B #endif Closes a conditional block. .TP .B #else Implements alternate path for a conditional block. .TP .B #ifdef DEFINE True only if macro .B DEFINE is defined. .TP .B #ifndef DEFINE The opposite; true only if macro .B DEFINE has not been previously defined. .TP .B #if expression True if expression .B expression evaluates to non-zero. .B expression may reference other macros. .TP .B #iflused label True if label .B label has been used (but not necessarily instantiated with a value). .I This works on labels, not macros! .TP .B #ifldef label True if label .B label is defined .I and assigned with a value. .I This works on labels, not macros! .LP Unclosed conditional blocks at the end of included files generate warnings; unclosed conditional blocks at the end of assembly generate an error. .LP .B #iflused and .B #ifldef are useful for building up a library based on labels. For example, you might use something like this in your library's code: .IP .B #iflused label .br .B #ifldef label .br .B #echo label already defined, library function label cannot be inserted .br .B #else .br .B label /* your code */ .br .B #endif .br .B #endif .SH ENVIRONMENT .B xa utilises the following environment variables, if they exist: .TP .B XAINPUT Include file path; components should be separated by `,'. .TP .B XAOUTPUT Output file path. .SH NOTES'N'BUGS The R65C02 instructions .B ina (often rendered .B inc .BR a ) and .B dea .RB ( dec .BR a ) must be rendered as bare .B inc and .B dec instructions respectively. .LP The 65816 instructions .B mvn and .B mvp use two eight bit parameters, the only instructions in the entire instruction set to do so. Older versions of .B xa took a single 16-bit absolute value. Since 2.3.7, the standard syntax is now accepted and the old syntax is deprecated (a warning will be generated). .LP Forward-defined labels -- that is, labels that are defined after the current instruction is processed -- cannot be optimized into zero page instructions even if the label does end up being defined as a zero page location, because the assembler does not know the value of the label in advance during the first pass when the length of an instruction is computed. On the second pass, a warning will be issued when an instruction that could have been optimized can't be because of this limitation. (Obviously, this does not apply to branching or jumping instructions because they're not optimizable anyhow, and those instructions that can .I only take an 8-bit parameter will always be casted to an 8-bit quantity.) If the label cannot otherwise be defined ahead of the instruction, the backtick prefix .B ` may be used to force further optimization no matter where the label is defined as long as the instruction supports it. Indiscriminately forcing the issue can be fraught with peril, however, and is not recommended; to discourage this, the assembler will complain about its use in addressing mode situations where no ambiguity exists, such as indirect indexed, branching and so on. .LP Also, as a further consequence of the way optimization is managed, we repeat that .B all 24-bit quantities and labels that reference a 24-bit quantity in 65816 mode, anteriorly declared or otherwise, .B MUST be prepended with the .B @ prefix. Otherwise, the assembler will attempt to optimize to 16 bits, which may be undesirable. .SH "SEE ALSO" .BR file65 (1), .BR ldo65 (1), .BR printcbm (1), .BR reloc65 (1), .BR uncpk (1), .BR dxa (1) .SH AUTHOR This manual page was written by David Weinehall , Andre Fachat and Cameron Kaiser . Original xa package (C)1989-1997 Andre Fachat. Additional changes (C)1989-2017 Andre Fachat, Jolse Maginnis, David Weinehall, Cameron Kaiser. The official maintainer is Cameron Kaiser. .SH WEBSITE http://www.floodgap.com/retrotech/xa/ xa-2.3.8/misc/0000700000031500000010000000000012447656107012403 5ustar spectrestaffxa-2.3.8/misc/Makefile0000600000031500000010000000145112003602214014020 0ustar spectrestaff XCBMLIB = .. # -Wall -ansi et al. cause compile problems. CFLAGS = -O2 LIBS = #-lncurses -ltermcap -lm all: ../mkrom.sh ../uncpk ../printcbm ../file65 ../reloc65 ../ldo65 ../uncpk: uncpk.c ${CC} ${CFLAGS} uncpk.c -o $(XCBMLIB)/uncpk ../printcbm: printcbm.c ${CC} ${CFLAGS} printcbm.c -o $(XCBMLIB)/printcbm ../file65: file65.c ${CC} ${CFLAGS} file65.c -o $(XCBMLIB)/file65 ../ldo65: ldo65.c ${CC} ${CFLAGS} ldo65.c -o $(XCBMLIB)/ldo65 ../reloc65: reloc65.c ${CC} ${CFLAGS} reloc65.c -o $(XCBMLIB)/reloc65 ../mkrom.sh: mkrom.sh cp mkrom.sh ../mkrom.sh lt1: lt1.a ../xa -R -c -o lt1 lt1.a lt2: lt2.a ../xa -R -c -o lt2 lt2.a lt: lt1 lt2 ../ldo65 -o lt lt1 lt2 clean: rm -f *.o mrproper: clean rm -f ../uncpk ../printcbm ../file65 ../mkrom.sh ../reloc65 ../ldo65 rm -f lt1 lt2 lt xa-2.3.8/misc/file65.c0000600000031500000010000001762612357614750013655 0ustar spectrestaff/* file65 -- A part of xa65 - 65xx/65816 cross-assembler and utility suite * Print information about o65 files * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _MSC_VER #include #endif #include #include #include #include #include #include #include "version.h" #define BUF (9*4+8) #define programname "file65" #define progversion "v0.2.1" #define author "Written by Andre Fachat" #define copyright "Copyright (C) 1997-2002 Andre Fachat." int read_options(FILE *fp); int print_labels(FILE *fp, int offset); unsigned char hdr[BUF]; unsigned char cmp[] = { 1, 0, 'o', '6', '5' }; int xapar = 0; int rompar = 0; int romoff = 0; int labels = 0; void usage(FILE *fp) { fprintf(fp, "Usage: %s [options] [file]\n" "Print file information about o65 files\n" "\n", programname); fprintf(fp, " -P print the segment end addresses according to `xa' command line\n" " parameters `-b?'\n" " -a offset print `xa' ``romable'' parameter for another file behind this one\n" " in the same ROM. Add offset to start address.\n" " -A offset same as `-a', but only print the start address of the next\n" " file in the ROM\n" " -V print undefined and global labels\n" " --version output version information and exit\n" " --help display this help and exit\n"); } int main(int argc, char *argv[]) { int i = 1, n, mode, hlen; FILE *fp; char *aligntxt[4]= {"[align 1]","[align 2]","[align 4]","[align 256]"}; if(argc<=1) { usage(stderr); exit(1); } if (strstr(argv[1], "--help")) { usage(stdout); exit(0); } if (strstr(argv[1], "--version")) { version(programname, progversion, author, copyright); exit(0); } while(i=8) && (!memcmp(hdr, cmp, 5))) { mode=hdr[7]*256+hdr[6]; if(!xapar && !rompar) { printf("%s: o65 version %d %s file\n", argv[i], hdr[5], hdr[7]&0x10 ? "object" : "executable"); printf(" mode: %04x =",mode ); printf("%s%s%s%s%s\n", (mode & 0x1000)?"[object]":"[executable]", (mode & 0x2000)?"[32bit]":"[16bit]", (mode & 0x4000)?"[page relocation]":"[byte relocation]", (mode & 0x8000)?"[CPU 65816]":"[CPU 6502]", aligntxt[mode & 3]); } if(mode & 0x2000) { fprintf(stderr,"file65: %s: 32 bit size not supported\n", argv[i]); } else { n=fread(hdr+8, 1, 18, fp); if(n<18) { fprintf(stderr,"file65: %s: truncated file\n", argv[i]); } else { if(!xapar && !rompar) { printf(" text segment @ $%04x - $%04x [$%04x bytes]\n", hdr[9]*256+hdr[8], hdr[9]*256+hdr[8]+hdr[11]*256+hdr[10], hdr[11]*256+hdr[10]); printf(" data segment @ $%04x - $%04x [$%04x bytes]\n", hdr[13]*256+hdr[12], hdr[13]*256+hdr[12]+hdr[15]*256+hdr[14], hdr[15]*256+hdr[14]); printf(" bss segment @ $%04x - $%04x [$%04x bytes]\n", hdr[17]*256+hdr[16], hdr[17]*256+hdr[16]+hdr[19]*256+hdr[18], hdr[19]*256+hdr[18]); printf(" zero segment @ $%04x - $%04x [$%04x bytes]\n", hdr[21]*256+hdr[20], hdr[21]*256+hdr[20]+hdr[23]*256+hdr[22], hdr[23]*256+hdr[22]); printf(" stack size $%04x bytes %s\n", hdr[25]*256+hdr[24], (hdr[25]*256+hdr[24])==0?"(i.e. unknown)":""); if(labels) { read_options(fp); print_labels(fp, hdr[11]*256+hdr[10] + hdr[15]*256+hdr[14]); } } else { struct stat fbuf; hlen = 8+18+read_options(fp); stat(argv[i],&fbuf); if(xapar) { if(!rompar) printf("-bt %d ", (hdr[9]*256+hdr[8]) + (hdr[11]*256+hdr[10]) ); printf("-bd %d -bb %d -bz %d ", (hdr[13]*256+hdr[12]) + (hdr[15]*256+hdr[14]), (hdr[17]*256+hdr[16]) + (hdr[19]*256+hdr[18]), (hdr[21]*256+hdr[20]) + (hdr[23]*256+hdr[22]) ); } if(rompar==1) { printf("-A %lu ", (unsigned long)((hdr[9]*256+hdr[8]) -hlen +romoff +(fbuf.st_size))); } else if(rompar==2) { printf("%lu ", (unsigned long)((hdr[9]*256+hdr[8]) -hlen +romoff +(fbuf.st_size))); } printf("\n"); } } } } else { fprintf(stderr,"file65: %s: not an o65 file!\n", argv[i]); if(hdr[0]==1 && hdr[1]==8 && hdr[3]==8) { printf("%s: C64 BASIC executable (start address $0801)?\n", argv[i]); } else if(hdr[0]==1 && hdr[1]==4 && hdr[3]==4) { printf("%s: CBM PET BASIC executable (start address $0401)?\n", argv[i]); } } } else { fprintf(stderr,"file65: %s: %s\n", argv[i], strerror(errno)); } } i++; } return 0; } static struct { int opt; int strfl; char *string; } otab[] = { { 0, 1, "Filename" }, { 1, 0, "O/S Type" }, { 2, 1, "Assembler" }, { 3, 1, "Author" }, { 4, 1, "Creation Date" }, { -1, -1, NULL } }; static char* stab[] = { "undefined" , "absolute" , "text" , "data" , "bss" , "zero" , "-" , "-" }; void print_option(unsigned char *buf, int len) { int i, strfl=0; for(i=0;otab[i].opt>=0; i++) if(*buf==otab[i].opt) break; if(otab[i].opt>=0) { printf("fopt: %-17s: ", otab[i].string); strfl = otab[i].strfl; } else { printf("fopt: Unknown Type $%02x : ", (*buf & 0xff)); } if(strfl) { buf[len]=0; printf("%s\n", buf+1); } else { for (i=1; i #include #include #include #ifndef _MSC_VER #include #endif #include #include "version.h" #define BUF (9*2+8) /* 16 bit header */ #define programname "ldo65" #define progversion "v0.1.1" #define author "Written by Andre Fachat" #define copyright "Copyright (C) 1997-2002 Andre Fachat. Formerly ld65." typedef struct { char *name; int len; } undefs; /* file information */ typedef struct { char *fname; /* file name */ size_t fsize; /* length of file */ unsigned char *buf; /* file content */ int tbase; /* header: text base */ int tlen; /* text length */ int dbase; /* data base */ int dlen; /* data length */ int bbase; /* bss base */ int blen; /* bss length */ int zbase; /* zero base */ int zlen; /* zero length */ int tdiff; /* text segment relocation diff */ int ddiff; /* data segment relocation diff */ int bdiff; /* bss segment relocation diff */ int zdiff; /* zero segment relocation diff */ int tpos; /* position of text segment in file */ int dpos; /* position of data segment in file */ int upos; /* position of undef'd list in file */ int trpos; /* position of text reloc tab in file */ int drpos; /* position of data reloc tab in file */ int gpos; /* position of globals list in file */ int lasttreloc; int lastdreloc; int nundef; /* number of undefined labels */ undefs *ud; /* undefined labels list NULL if none */ } file65; /* globally defined lables are stored in this struct */ typedef struct { char *name; int len; /* length of labelname */ int fl; /* 0=ok, 1=multiply defined */ int val; /* address value */ int seg; /* segment */ file65 *file; /* in which file is it? */ } glob; file65 *load_file(char *fname); int read_options(unsigned char *f); int read_undef(unsigned char *f, file65 *fp); int len_reloc_seg(unsigned char *buf, int ri); int reloc_seg(unsigned char *buf, int adr, int ri, int *lreloc, file65 *fp); unsigned char *reloc_globals(unsigned char *, file65 *fp); int read_globals(file65 *file); int write_options(FILE *fp, file65 *file); int write_reloc(file65 *fp[], int nfp, FILE *f); int write_globals(FILE *fp); file65 file; unsigned char cmp[] = { 1, 0, 'o', '6', '5' }; unsigned char hdr[26] = { 1, 0, 'o', '6', '5', 0 }; void usage(FILE *fp) { fprintf(fp, "Usage: %s [OPTION]... [FILE]...\n" "Linker for o65 object files\n" "\n" " -b? addr relocates segment `?' (i.e. `t' for text segment,\n" " `d' for data, `b' for bss, and `z' for zeropage) to the new\n" " address `addr'\n" " -o file uses `file' as output file. Default is `a.o65'\n" " -G suppress writing of globals\n" " --version output version information and exit\n" " --help display this help and exit\n", programname); } int main(int argc, char *argv[]) { int noglob=0; int i = 1; int tbase = 0x0400, dbase = 0x1000, bbase = 0x4000, zbase = 0x0002; int ttlen, tdlen, tblen, tzlen; char *outfile = "a.o65"; int j, jm; file65 *file, **fp = NULL; FILE *fd; if (argc <= 1) { usage(stderr); exit(1); } if (strstr(argv[1], "--help")) { usage(stdout); exit(0); } if (strstr(argv[1], "--version")) { version(programname, progversion, author, copyright); exit(0); } /* read options */ while(i=jm) fp=realloc(fp, (jm=(jm?jm*2:10))*sizeof(file65*)); if(!fp) { fprintf(stderr,"Oops, no more memory\n"); exit(1); } fp[j++] = f; } i++; } /* now [tdbz]base holds new segment base address */ /* set total length to zero */ ttlen = tdlen = tblen = tzlen = 0; /* find new addresses for the files and read globals */ for(i=0;itdiff = ((tbase + ttlen) - file->tbase); file->ddiff = ((dbase + tdlen) - file->dbase); file->bdiff = ((bbase + tblen) - file->bbase); file->zdiff = ((zbase + tzlen) - file->zbase); /*printf("tbase=%04x, file->tbase=%04x, ttlen=%04x -> tdiff=%04x\n", tbase, file->tbase, ttlen, file->tdiff);*/ /* update globals (for result file) */ ttlen += file->tlen; tdlen += file->dlen; tblen += file->blen; tzlen += file->zlen; read_globals(file); } for(i=0;ibuf, file->tpos, file->trpos, &(file->lasttreloc), file); reloc_seg(file->buf, file->dpos, file->drpos, &(file->lastdreloc), file); reloc_globals(file->buf+file->gpos, file); file->tbase += file->tdiff; file->dbase += file->ddiff; file->bbase += file->bdiff; file->zbase += file->zdiff; file->lasttreloc += file->tbase - file->tpos; file->lastdreloc += file->dbase - file->dpos; } hdr[ 6] = 0; hdr[ 7] = 0; hdr[ 8] = tbase & 255; hdr[ 9] = (tbase>>8) & 255; hdr[10] = ttlen & 255; hdr[11] = (ttlen >>8)& 255; hdr[12] = dbase & 255; hdr[13] = (dbase>>8) & 255; hdr[14] = tdlen & 255; hdr[15] = (tdlen >>8)& 255; hdr[16] = bbase & 255; hdr[17] = (bbase>>8) & 255; hdr[18] = tblen & 255; hdr[19] = (tblen >>8)& 255; hdr[20] = zbase & 255; hdr[21] = (zbase>>8) & 255; hdr[22] = tzlen & 255; hdr[23] = (tzlen >>8)& 255; hdr[24] = 0; hdr[25] = 0; fd = fopen(outfile, "wb"); if(!fd) { fprintf(stderr,"Couldn't open output file %s (%s)\n", outfile, strerror(errno)); exit(2); } fwrite(hdr, 1, 26, fd); /* this writes _all_ options from _all_files! */ for(i=0;ibuf + fp[i]->tpos, 1, fp[i]->tlen, fd); } /* write data segment */ for(i=0;ibuf + fp[i]->dpos, 1, fp[i]->dlen, fd); } write_reloc(fp, j, fd); if(!noglob) { write_globals(fd); } else { fputc(0,fd); fputc(0,fd); } fclose(fd); return 0; } /***************************************************************************/ int write_options(FILE *fp, file65 *file) { return fwrite(file->buf+BUF, 1, file->tpos-BUF-1, fp); } int read_options(unsigned char *buf) { int c, l=0; c=buf[0]; while(c && c!=EOF) { c&=255; l+=c; c=buf[l]; } return ++l; } int read_undef(unsigned char *buf, file65 *file) { int i, n, l = 2, ll; n = buf[0] + 256*buf[1]; file->nundef = n; if (n == 0) { file->ud = NULL; } else { file->ud = malloc(n*sizeof(undefs)); if(!file->ud) { fprintf(stderr,"Oops, no more memory\n"); exit(1); } i=0; while(iud[i].name = (char*) buf+l; ll=l; while(buf[l++]); file->ud[i].len = l-ll-1; /*printf("read undef '%s'(%p), len=%d, ll=%d, l=%d, buf[l]=%d\n", file->ud[i].name, file->ud[i].name, file->ud[i].len,ll,l,buf[l]);*/ i++; } } return l; } /* compute and return the length of the relocation table */ int len_reloc_seg(unsigned char *buf, int ri) { int type, seg; while(buf[ri]) { if((buf[ri] & 255) == 255) { ri++; } else { ri++; type = buf[ri] & 0xe0; seg = buf[ri] & 0x07; /*printf("reloc entry @ rtab=%p (offset=%d), adr=%04x, type=%02x, seg=%d\n",buf+ri-1, *(buf+ri-1), adr, type, seg);*/ ri++; switch(type) { case 0x80: break; case 0x40: ri++; break; case 0x20: break; } if(seg==0) ri+=2; } } return ++ri; } #define reldiff(s) (((s)==2)?fp->tdiff:(((s)==3)?fp->ddiff:(((s)==4)?fp->bdiff:(((s)==5)?fp->zdiff:0)))) unsigned char *reloc_globals(unsigned char *buf, file65 *fp) { int n, old, new, seg; n = buf[0] + 256*buf[1]; buf +=2; while(n) { /*printf("relocating %s, ", buf);*/ while(*(buf++)); seg = *buf; old = buf[1] + 256*buf[2]; new = old + reldiff(seg); /*printf("old=%04x, seg=%d, rel=%04x, new=%04x\n", old, seg, reldiff(seg), new);*/ buf[1] = new & 255; buf[2] = (new>>8) & 255; buf +=3; n--; } return buf; } /***************************************************************************/ file65 *load_file(char *fname) { file65 *file; struct stat fs; FILE *fp; int mode, hlen; size_t n; file=malloc(sizeof(file65)); if(!file) { fprintf(stderr,"Oops, not enough memory!\n"); exit(1); } /*printf("load_file(%s)\n",fname);*/ file->fname=fname; stat(fname, &fs); file->fsize=fs.st_size; file->buf=malloc(file->fsize); if(!file->buf) { fprintf(stderr,"Oops, no more memory!\n"); exit(1); } fp = fopen(fname,"rb"); if(fp) { n = fread(file->buf, 1, file->fsize, fp); fclose(fp); if((n>=file->fsize) && (!memcmp(file->buf, cmp, 5))) { mode=file->buf[7]*256+file->buf[6]; if(mode & 0x2000) { fprintf(stderr,"file65: %s: 32 bit size not supported\n", fname); free(file->buf); free(file); file=NULL; } else if(mode & 0x4000) { fprintf(stderr,"file65: %s: pagewise relocation not supported\n", fname); free(file->buf); free(file); file=NULL; } else { hlen = BUF+read_options(file->buf+BUF); file->tbase = file->buf[ 9]*256+file->buf[ 8]; file->tlen = file->buf[11]*256+file->buf[10]; file->dbase = file->buf[13]*256+file->buf[12]; file->dlen = file->buf[15]*256+file->buf[14]; file->bbase = file->buf[17]*256+file->buf[16]; file->blen = file->buf[19]*256+file->buf[18]; file->zbase = file->buf[21]*256+file->buf[20]; file->zlen = file->buf[23]*256+file->buf[21]; file->tpos = hlen; file->dpos = hlen + file->tlen; file->upos = file->dpos + file->dlen; file->trpos= file->upos + read_undef(file->buf+file->upos, file); file->drpos= len_reloc_seg(file->buf, file->trpos); file->gpos = len_reloc_seg(file->buf, file->drpos); } } else fprintf(stderr,"file65: %s: %s\n", fname, strerror(errno)); } else fprintf(stderr,"file65: %s: %s\n", fname, strerror(errno)); return file; } /***************************************************************************/ glob *gp = NULL; int gm=0; int g=0; int write_reloc(file65 *fp[], int nfp, FILE *f) { int tpc, pc, i; unsigned char *p; int low = 0, seg, typ, lab; /* no undefined labels ? TODO */ fputc(0,f); fputc(0,f); tpc = fp[0]->tbase-1; for(i=0;itbase-1; p = fp[i]->buf + fp[i]->trpos; while(*p) { while((*p)==255) { pc+=254; p++; } pc+=*(p++); seg=(*p)&7; typ=(*p)&0xe0; if(typ==0x40) low=*(++p); p++; if(seg==0) { lab=p[0]+256*p[1]; seg=gp[lab].seg; p+=2; } if(seg>1) { while(pc-tpc>254) { fputc(255,f); tpc+=254; } fputc(pc-tpc, f); tpc=pc; fputc(typ | seg, f); if(typ==0x40) { fputc(low,f); } } } } fputc(0,f); tpc = fp[0]->dbase-1; for(i=0;idbase-1; p = fp[i]->buf + fp[i]->drpos; while(*p) { while((*p)==255) { pc+=254; p++; } pc+=*(p++); seg=(*p)&7; typ=(*p)&0xe0; if(typ==0x40) low=*(++p); p++; if(seg==0) { lab=p[0]+256*p[1]; seg=gp[lab].seg; p+=2; } if(seg>1) { while(pc-tpc>254) { fputc(255,f); tpc+=254; } fputc(pc-tpc, f); tpc=pc; fputc(typ | seg, f); if(typ==0x40) { fputc(low,f); } } } } fputc(0,f); return 0; } int write_globals(FILE *fp) { int i; fputc(g&255, fp); fputc((g>>8)&255, fp); for(i=0;i>8)&255); } return 0; } int read_globals(file65 *fp) { int i, l, n, old, new, seg, ll; char *name; unsigned char *buf = fp->buf + fp->gpos; n = buf[0] + 256*buf[1]; buf +=2; while(n) { /*printf("reading %s, ", buf);*/ name = (char*) buf; l=0; while(buf[l++]); buf+=l; ll=l-1; seg = *buf; old = buf[1] + 256*buf[2]; new = old + reldiff(seg); /*printf("old=%04x, seg=%d, rel=%04x, new=%04x\n", old, seg, reldiff(seg), new);*/ /* multiply defined? */ for(i=0;ifname, gp[i].file->fname); gp[i].fl = 1; break; } } /* not already defined */ if(i>=g) { if(g>=gm) { gp = realloc(gp, (gm=(gm?2*gm:40))*sizeof(glob)); if(!gp) { fprintf(stderr,"Oops, no more memory\n"); exit(1); } } if(g>=0x10000) { fprintf(stderr,"Outch, maximum number of labels (65536) exceeded!\n"); exit(3); } gp[g].name = name; gp[g].len = ll; gp[g].seg = seg; gp[g].val = new; gp[g].fl = 0; gp[g].file = fp; /*printf("set label '%s' (l=%d, seg=%d, val=%04x)\n", gp[g].name, gp[g].len, gp[g].seg, gp[g].val);*/ g++; } buf +=3; n--; } return 0; } int find_global(unsigned char *bp, file65 *fp, int *seg) { int i,l; char *n; int nl = bp[0]+256*bp[1]; l=fp->ud[nl].len; n=fp->ud[nl].name; /*printf("find_global(%s (len=%d))\n",n,l);*/ for(i=0;i>8) & 255; /*printf("return gp[%d]=%s (len=%d), val=%04x\n",i,gp[i].name,gp[i].len,gp[i].val);*/ return gp[i].val; } } fprintf(stderr,"Warning: undefined label '%s' in file %s\n", n, fp->fname); return 0; } int reloc_seg(unsigned char *buf, int pos, int ri, int *lreloc, file65 *fp) { int type, seg, old, new; /* pos = position of segment in *buf ri = position of relocation table in *buf */ pos--; /*printf("reloc_seg: adr=%04x, tdiff=%04x, ddiff=%04x, bdiff=%04x, zdiff=%04x\n", pos, fp->tdiff, fp->ddiff, fp->bdiff, fp->zdiff); */ while(buf[ri]) { if((buf[ri] & 255) == 255) { pos += 254; ri++; } else { pos += buf[ri] & 255; ri++; type = buf[ri] & 0xe0; seg = buf[ri] & 0x07; /*printf("reloc entry @ ri=%04x, pos=%04x, type=%02x, seg=%d\n",ri, pos, type, seg);*/ ri++; switch(type) { case 0x80: old = buf[pos] + 256*buf[pos+1]; if(seg) { new = old + reldiff(seg); } else { new = old + find_global(buf+ri, fp, &seg); ri += 2; /* account for label number */ } /*printf("old=%04x, new=%04x\n",old,new);*/ buf[pos] = new & 255; buf[pos+1] = (new>>8)&255; break; case 0x40: old = buf[pos]*256 + buf[ri]; if(seg) { new = old + reldiff(seg); } else { new = old + find_global(buf+ri+1, fp, &seg); ri += 2; /* account for label number */ } buf[pos] = (new>>8)&255; buf[ri] = new & 255; ri++; break; case 0x20: old = buf[pos]; if(seg) { new = old + reldiff(seg); } else { new = old + find_global(buf+ri, fp, &seg); ri += 2; /* account for label number */ } buf[pos] = new & 255; break; } } } *lreloc = pos; return ++ri; } xa-2.3.8/misc/mkrom.sh0000700000031500000010000000367206263221755014073 0ustar spectrestaff#!/bin/bash # # xa65 - 6502 cross assembler and utility suite # mkrom.sh - assemble several 'romable' files into one binary # Copyright (C) 1997 André Fachat (a.fachat@physik.tu-chemnitz.de) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # XA="../xa" FILE=../file65 start=32768 ende=65536 romfile=rom65 next=$[ start + 2 ]; pars="-A $next" umask 077 tmp1=/tmp/mkrom65.sh.$$.a tmp2=/tmp/mkrom65.sh.$$.b tmp3=/tmp/mkrom65.sh.$$.c echo -e "#include \nvoid main(int argc, char *argv[]) { printf(\"%c%c\",atoi(argv[1])&255,(atoi(argv[1])/256)&255);}" \ > $tmp3; cc $tmp3 -o $tmp2 while [ $# -ne 0 ]; do case $1 in -A) # get start address start=$[ $2 ]; shift ;; -E) # get end address ende=$[ $2 ]; shift ;; -R) # get ROM filename romfile=$2; shift ;; -O) # xa options XA="$XA $2"; shift ;; -S) # segment addresses - in xa option format pars="$pars $2"; shift ;; *) break; ;; esac; shift done #get file list list="$*" echo -n > $romfile for i in $list; do #echo "next=$next, start=$start, pars=$pars" #echo "cmd= ${XA} -R $pars -o $tmp1 $i" $XA -R $pars -o $tmp1 $i pars=`$FILE -a 2 -P $tmp1`; next=`$FILE -A 0 $tmp1`; $tmp2 $next >> $romfile cat $tmp1 >> $romfile; done; $tmp2 65535 >> $romfile rm -f $tmp1 $tmp2 $tmp3 xa-2.3.8/misc/printcbm.c0000600000031500000010000000530712357614601014365 0ustar spectrestaff/* printcbm -- A part of xa65 - 65xx/65816 cross-assembler and utility suite * list CBM BASIC programs * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include "version.h" #define programname "printcbm" #define progversion "v1.0.0" #define author "Written by Andre Fachat" #define copyright "Copyright (C) 1997-2002 Andre Fachat." char *cmd[] = { "end", "for", "next", "data", "input#", "input", "dim", "read", "let", "goto", "run", "if", "restore", "gosub", "return", "rem", "stop", "on", "wait", "load", "save", "verify", "def", "poke", "print#", "print", "cont", "list", "clr", "cmd", "sys", "open", "close", "get", "new", "tab(", "to", "fn", "spc(", "then", "not", "step", "+", "-", "*", "/", "^", "and", "or", ">", "=", "<", "sgn", "int", "abs", "usr", "fre", "pos", "sqr", "rnd", "log", "exp", "cos", "sin", "tan", "atn", "peek", "len", "str$", "val", "asc", "chr$", "left$", "right$", "mid$", "go" }; void usage(FILE *fp) { fprintf(fp, "Usage: %s [OPTION]... [FILE]...\n" "List CBM BASIC programs\n" "\n" " --version output version information and exit\n" " --help display this help and exit\n", programname); } int main(int argc, char *argv[]) { FILE *fp; int a, b, c; if (argc < 2) { usage(stderr); exit(1); } if (strstr(argv[1], "--help")) { usage(stdout); exit(0); } if (strstr(argv[1], "--version")) { version(programname, progversion, author, copyright); exit(0); } fp = fopen(argv[1], "rb"); if (fp) { b = fgetc(fp); b = fgetc(fp); while (b != EOF) { a = fgetc(fp); a = a + 256 * fgetc(fp); if (a) { a = fgetc(fp); a = a + 256 * fgetc(fp); printf("%d ", a); while ((c = fgetc(fp))) { if (c == EOF) break; if (c >= 0x80 && c < 0xcc) printf("%s", cmd[c - 0x80]); else printf("%c", c); } printf("\n"); } else { break; } } fclose(fp); } else { printf("File %s not found!\n", argv[1]); } return 0; } xa-2.3.8/misc/reloc65.c0000600000031500000010000002366212357614632014036 0ustar spectrestaff/* reloc65 -- A part of xa65 - 65xx/65816 cross-assembler and utility suite * o65 file relocator * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include "version.h" #define BUF (9*2+8) /* 16 bit header */ #define programname "reloc65" #define progversion "v0.2.1" #define author "Written by Andre Fachat" #define copyright "Copyright (C) 1997-2002 Andre Fachat." typedef struct { char *fname; size_t fsize; unsigned char *buf; int tbase, tlen, dbase, dlen, bbase, blen, zbase, zlen; int tdiff, ddiff, bdiff, zdiff; unsigned char *segt; unsigned char *segd; unsigned char *utab; unsigned char *rttab; unsigned char *rdtab; unsigned char *extab; } file65; int read_options(unsigned char *f); int read_undef(unsigned char *f); unsigned char *reloc_seg(unsigned char *f, int len, unsigned char *rtab, file65 *fp, int undefwarn); unsigned char *reloc_globals(unsigned char *, file65 *fp); file65 file; unsigned char cmp[] = { 1, 0, 'o', '6', '5' }; void usage(FILE *fp) { fprintf(fp, "Usage: %s [OPTION]... [FILE]...\n" "Relocator for o65 object files\n" "\n" " -b? addr relocates segment '?' (i.e. 't' for text segment,\n" " 'd' for data, 'b' for bss and 'z' for zeropage) to the new\n" " address `addr'\n" " -o file uses `file' as output file. Default is `a.o65'\n" " -x? extracts text `?' = `t' or data `?' = `d' segment from file\n", programname); fprintf(fp, " instead of writing back the whole file\n" " -X extracts the file such that text and data\n" " segments are chained, i.e. possibly relocating\n" " the data segment to the end of the text segment\n" " --version output version information and exit\n" " --help display this help and exit\n"); } int main(int argc, char *argv[]) { int i = 1, mode, hlen; size_t n; FILE *fp; int tflag = 0, dflag = 0, bflag = 0, zflag = 0; int tbase = 0, dbase = 0, bbase = 0, zbase = 0; char *outfile = "a.o65"; int extract = 0; if (argc <= 1) { usage(stderr); exit(1); } if (strstr(argv[1], "--help")) { usage(stdout); exit(0); } if (strstr(argv[1], "--version")) { version(programname, progversion, author, copyright); exit(0); } while(i %s\n",argv[i],outfile); fp = fopen(argv[i],"rb"); if(fp) { n = fread(file.buf, 1, file.fsize, fp); fclose(fp); if((n>=file.fsize) && (!memcmp(file.buf, cmp, 5))) { mode=file.buf[7]*256+file.buf[6]; if(mode & 0x2000) { fprintf(stderr,"reloc65: %s: 32 bit size not supported\n", argv[i]); } else if(mode & 0x4000) { fprintf(stderr,"reloc65: %s: pagewise relocation not supported\n", argv[i]); } else { hlen = BUF+read_options(file.buf+BUF); file.tbase = file.buf[ 9]*256+file.buf[ 8]; file.tlen = file.buf[11]*256+file.buf[10]; file.tdiff = tflag? tbase - file.tbase : 0; file.dbase = file.buf[13]*256+file.buf[12]; file.dlen = file.buf[15]*256+file.buf[14]; if (extract == 3) { if (dflag) { fprintf(stderr,"reloc65: %s: Warning: data segment address ignored for -X option\n", argv[i]); } dbase = file.tbase + file.tdiff + file.tlen; file.ddiff = dbase - file.dbase; } else { file.ddiff = dflag? dbase - file.dbase : 0; } file.bbase = file.buf[17]*256+file.buf[16]; file.blen = file.buf[19]*256+file.buf[18]; file.bdiff = bflag? bbase - file.bbase : 0; file.zbase = file.buf[21]*256+file.buf[20]; file.zlen = file.buf[23]*256+file.buf[21]; file.zdiff = zflag? zbase - file.zbase : 0; file.segt = file.buf + hlen; file.segd = file.segt + file.tlen; file.utab = file.segd + file.dlen; file.rttab = file.utab + read_undef(file.utab); file.rdtab = reloc_seg(file.segt, file.tlen, file.rttab, &file, extract); file.extab = reloc_seg(file.segd, file.dlen, file.rdtab, &file, extract); reloc_globals(file.extab, &file); if(tflag) { file.buf[ 9]= (tbase>>8)&255; file.buf[ 8]= tbase & 255; } if(dflag) { file.buf[13]= (dbase>>8)&255; file.buf[12]= dbase & 255; } if(bflag) { file.buf[17]= (bbase>>8)&255; file.buf[16]= bbase & 255; } if(zflag) { file.buf[21]= (zbase>>8)&255; file.buf[20]= zbase & 255; } fp = fopen(outfile, "wb"); if(fp) { switch(extract) { case 0: /* whole file */ fwrite(file.buf, 1, file.fsize, fp); break; case 1: /* text segment */ fwrite(file.segt, 1, file.tlen, fp); break; case 2: /* data segment */ fwrite(file.segd, 1, file.dlen, fp); break; case 3: /* text+data */ fwrite(file.segt, 1, file.tlen, fp); fwrite(file.segd, 1, file.dlen, fp); break; } fclose(fp); } else { fprintf(stderr,"reloc65: write '%s': %s\n", outfile, strerror(errno)); } } } else { fprintf(stderr,"reloc65: %s: not an o65 file!\n", argv[i]); if(file.buf[0]==1 && file.buf[1]==8 && file.buf[3]==8) { printf("%s: C64 BASIC executable (start address $0801)?\n", argv[i]); } else if(file.buf[0]==1 && file.buf[1]==4 && file.buf[3]==4) { printf("%s: CBM PET BASIC executable (start address $0401)?\n", argv[i]); } } } else { fprintf(stderr,"reloc65: read '%s': %s\n", argv[i], strerror(errno)); } } i++; } exit(0); } int read_options(unsigned char *buf) { int c, l=0; c=buf[0]; while(c && c!=EOF) { c&=255; l+=c; c=buf[l]; } return ++l; } int read_undef(unsigned char *buf) { int n, l = 2; n = buf[0] + 256*buf[1]; while(n){ n--; while(buf[l] != 0) { l++; } l++; } return l; } #define reldiff(s) (((s)==2)?fp->tdiff:(((s)==3)?fp->ddiff:(((s)==4)?fp->bdiff:(((s)==5)?fp->zdiff:0)))) unsigned char *reloc_seg(unsigned char *buf, int len, unsigned char *rtab, file65 *fp, int undefwarn) { int adr = -1; int type, seg, old, new; /*printf("tdiff=%04x, ddiff=%04x, bdiff=%04x, zdiff=%04x\n", fp->tdiff, fp->ddiff, fp->bdiff, fp->zdiff);*/ while(*rtab) { if((*rtab & 255) == 255) { adr += 254; rtab++; } else { adr += *rtab & 255; rtab++; type = *rtab & 0xe0; seg = *rtab & 0x07; /*printf("reloc entry @ rtab=%p (offset=%d), adr=%04x, type=%02x, seg=%d\n",rtab-1, *(rtab-1), adr, type, seg);*/ rtab++; switch(type) { case 0x80: /* WORD - two byte address */ old = buf[adr] + 256*buf[adr+1]; new = old + reldiff(seg); buf[adr] = new & 255; buf[adr+1] = (new>>8)&255; break; case 0x40: /* HIGH - high byte of an address */ old = buf[adr]*256 + *rtab; new = old + reldiff(seg); buf[adr] = (new>>8)&255; *rtab = new & 255; rtab++; break; case 0x20: /* LOW - low byt of an address */ old = buf[adr]; new = old + reldiff(seg); buf[adr] = new & 255; break; } if(seg==0) { /* undefined segment entry */ if (undefwarn) { fprintf(stderr,"reloc65: %s: Warning: undefined relocation table entry not handled!\n", fp->fname); } rtab+=2; } } } if(adr > len) { fprintf(stderr,"reloc65: %s: Warning: relocation table entries past segment end!\n", fp->fname); fprintf(stderr, "reloc65: adr=%x len=%x\n", adr, len); } return ++rtab; } unsigned char *reloc_globals(unsigned char *buf, file65 *fp) { int n, old, new, seg; n = buf[0] + 256*buf[1]; buf +=2; while(n) { /*printf("relocating %s, ", buf);*/ while(*(buf++)); seg = *buf; old = buf[1] + 256*buf[2]; new = old + reldiff(seg); /*printf("old=%04x, seg=%d, rel=%04x, new=%04x\n", old, seg, reldiff(seg), new);*/ buf[1] = new & 255; buf[2] = (new>>8) & 255; buf +=3; n--; } return buf; } xa-2.3.8/misc/uncpk.c0000600000031500000010000001114312357614647013674 0ustar spectrestaff/* reloc65 -- A part of xa65 - 65xx/65816 cross-assembler and utility suite * Pack/Unpack cpk archive files * * Copyright (C) 1989-2002 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include "version.h" #define max(a, b) (a > b) ? a : b #define min(a, b) (a < b) ? a : b #define programname "uncpk" #define progversion "v0.2.1" #define author "Written by Andre Fachat" #define copyright "Copyright (C) 1997-2002 Andre Fachat." FILE *fp; char name[100]; char *s; void usage(FILE *fp) { fprintf(fp, "Usage: %s [OPTION]... [FILE]...\n" "Manage c64 cpk archives\n" "\n" " c create an archive\n" " a add a file to an archive\n" " x extract archive\n" " l list contents of archive\n" " v verbose output\n" " --version output version information and exit\n" " --help display this help and exit\n", programname); } int list=0,verbose=0,add=0,create=0; int main(int argc, char *argv[]) { int i,c,c2,fileok, nc; size_t n,n2; FILE *fp,*fpo=NULL; if (argc <= 1) { usage(stderr); exit(1); } if (strstr(argv[1], "--help")) { usage(stdout); exit(0); } if (strstr(argv[1], "--version")) { version(programname, progversion, author, copyright); exit(0); } if(strchr(argv[1],(int)'l')) { list=1; } if(strchr(argv[1],(int)'v')) { verbose=1; } if(strchr(argv[1],(int)'a')) { add=1; } if(strchr(argv[1],(int)'c')) { create=1; } if(add||create) { if (argc <= 3) { usage(stderr); exit(1); } if(add) { fpo=fopen(argv[2],"ab"); } else if(create) { fpo=fopen(argv[2],"wb"); } if(fpo) { if(!add) fputc(1,fpo); /* Version Byte */ for(i=3;i=4 || c==0xf7) { n2=min(255,n); fprintf(fpo,"\xf7%c%c",(char)n2,(char)c); n-=n2; } else { fputc(c,fpo); n--; } } c=c2; } fclose(fp); fputc(0xf7,fpo); fputc(0,fpo); } else { fprintf(stderr,"Couldn't open file '%s' for reading!",argv[i]); } } fclose(fpo); } else { fprintf(stderr,"Couldn't open file '%s' for writing!",argv[1]); } } else { if (argc != 3) { usage(stderr); exit(1); } fp=fopen(argv[2],"rb"); if(fp){ if(fgetc(fp)==1){ do{ /* read name */ i=0; while((c=fgetc(fp))){ if(c==EOF) break; name[i++]=c; } name[i++]='\0'; if(!c){ /* end of archive ? */ while((s=strchr(name,'/'))) *s=':'; if(verbose+list) printf("%s\n",name); if(!list) { fpo=fopen(name,"wb"); if(!fpo) { fprintf(stderr,"Couldn't open output file %s !\n",name); } } fileok=0; while((c=fgetc(fp))!=EOF){ /* test if 'compressed' */ if(c==0xf7){ nc=fgetc(fp); if(!nc) { fileok=1; break; } c=fgetc(fp); if(fpo) { /* extract */ if(nc!=EOF && c!=EOF) { nc &= 255; while(nc--) { fputc(c,fpo); } } } } else { if(fpo) { fputc(c,fpo); } } } if(fpo) { fclose(fpo); fpo=NULL; } if(!fileok) { fprintf(stderr,"Unexpected end of file!\n"); } } } while(c!=EOF); } else fprintf(stderr,"Wrong Version!\n"); fclose(fp); } else { fprintf(stderr,"File %s not found!\n",argv[1]); } } return(0); } xa-2.3.8/misc/version.h0000644000031500000010000000245407615405421014250 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __XA65_VERSION_H__ #define __XA65_VERSION_H__ void version(const char *programname, const char *progversion, const char *authors, const char *copyright) { fprintf(stdout, "%s (xa65) %s\n" "%s\n" "\n" "%s\n" "This is free software; see the source for " "copying conditions. There is NO\n" "warranty; not even for MERCHANTABILIY or " "FITNESS FOR A PARTICULAR PURPOSE.\n", programname, progversion, authors, copyright); } #endif /* __XA65_VERSION_H__ */ xa-2.3.8/src/0000700000031500000010000000000013125355333012226 5ustar spectrestaffxa-2.3.8/src/Makefile0000600000031500000010000000043510622502544013667 0ustar spectrestaffOBJ = xa.o xaa.o xal.o xap.o xat.o xar.o xar2.o xao.o xau.o xam.o xacharset.o #CFLAGS=-W -Wall -pedantic -ansi #-g #CFLAGS=-W -Wall -ansi -O2 #LD = ${CC} #LDFLAGS = "-lc" all: xa xa: ${OBJ} ${LD} -o ../xa ${OBJ} ${LDFLAGS} clean: rm -f *.o *.o65 mrproper: clean rm -f ../xa xa-2.3.8/src/version.h0000644000031500000010000000245407615405421014104 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __XA65_VERSION_H__ #define __XA65_VERSION_H__ void version(const char *programname, const char *progversion, const char *authors, const char *copyright) { fprintf(stdout, "%s (xa65) %s\n" "%s\n" "\n" "%s\n" "This is free software; see the source for " "copying conditions. There is NO\n" "warranty; not even for MERCHANTABILIY or " "FITNESS FOR A PARTICULAR PURPOSE.\n", programname, progversion, authors, copyright); } #endif /* __XA65_VERSION_H__ */ xa-2.3.8/src/xa.c0000600000031500000010000006603313125351144013010 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * maintained by Cameron Kaiser (ckaiser@floodgap.com) * * Main program * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #ifndef _MSC_VER #include #endif /* macros */ #include "xad.h" /* structs and defs */ #include "xah.h" #include "xah2.h" /* exported functions are defined here */ #include "xa.h" #include "xal.h" #include "xam.h" #include "xao.h" #include "xap.h" #include "xar.h" #include "xat.h" #include "xacharset.h" #include "version.h" /* ANZERR: total number of errors */ /* ANZWARN: total number of warnings */ #define ANZERR 64 #define ANZWARN 13 #define programname "xa" #define progversion "v2.3.8" #define authors "Written by Andre Fachat, Jolse Maginnis, David Weinehall and Cameron Kaiser" #define copyright "Copyright (C) 1989-2017 Andre Fachat, Jolse Maginnis, David Weinehall\nand Cameron Kaiser." /* exported globals */ int ncmos, cmosfl, w65816, n65816; int masm = 0; int nolink = 0; int romable = 0; int romaddr = 0; int noglob = 0; int showblk = 0; int crossref = 0; char altppchar; /* local variables */ static char out[MAXLINE]; static time_t tim1, tim2; static FILE *fpout, *fperr, *fplab; static int ner = 0; static int align = 1; static void printstat(void); static void usage(int, FILE *); static int setfext(char *, char *); static int x_init(void); static int pass1(void); static int pass2(void); static int puttmp(int); static int puttmps(signed char *, int); static void chrput(int); static int xa_getline(char *); static void lineout(void); static long ga_p1(void); static long gm_p1(void); /* text */ int memode,xmode; int segment; int tlen=0, tbase=0x1000; int dlen=0, dbase=0x0400; int blen=0, bbase=0x4000; int zlen=0, zbase=4; int fmode=0; int relmode=0; int pc[SEG_MAX]; /* segments */ int main(int argc,char *argv[]) { int er=1,i; signed char *s=NULL; char *tmpp; int mifiles = 5; int nifiles = 0; int verbose = 0; int oldfile = 0; int no_link = 0; char **ifiles; char *ofile; char *efile; char *lfile; char *ifile; char old_e[MAXLINE]; char old_l[MAXLINE]; char old_o[MAXLINE]; tim1=time(NULL); ncmos=0; n65816=0; cmosfl=1; w65816=0; /* default: 6502 only */ altppchar = '#' ; /* i.e., NO alternate char */ if((tmpp = strrchr(argv[0],'/'))) { tmpp++; } else { tmpp = argv[0]; } if( (!strcmp(tmpp,"xa65816")) || (!strcmp(tmpp,"XA65816")) || (!strcmp(tmpp,"xa816")) || (!strcmp(tmpp,"XA816")) ) { w65816 = 1; /* allow 65816 per default */ } /* default output charset for strings in quotes */ set_charset("ASCII"); ifiles = malloc(mifiles*sizeof(char*)); afile = alloc_file(); if (argc <= 1) { usage(w65816, stderr); exit(1); } if (strstr(argv[1], "--help")) { usage(w65816, stdout); exit(0); } if (strstr(argv[1], "--version")) { version(programname, progversion, authors, copyright); exit(0); } ofile="a.o65"; efile=NULL; lfile=NULL; if(pp_init()) { logout("fatal: pp: no memory!"); return 1; } if(b_init()) { logout("fatal: b: no memory!"); return 1; } if(l_init()) { logout("fatal: l: no memory!"); return 1; } i=1; while(i filename */ ifiles[nifiles++] = argv[i]; if(nifiles>=mifiles) { mifiles += 5; ifiles=realloc(ifiles, mifiles*sizeof(char*)); if(!ifiles) { fprintf(stderr, "Oops: couldn't alloc enough mem for filelist table..!\n"); exit(1); } } } i++; } if(!nifiles) { fprintf(stderr, "No input files given!\n"); exit(0); } if(oldfile) { strcpy(old_e, ifiles[0]); strcpy(old_o, ifiles[0]); strcpy(old_l, ifiles[0]); if(setfext(old_e,".err")==0) efile = old_e; if(setfext(old_o,".obj")==0) ofile = old_o; if(setfext(old_l,".lab")==0) lfile = old_l; } if(verbose) fprintf(stderr, "%s\n",copyright); fplab= lfile ? xfopen(lfile,"w") : NULL; fperr= efile ? xfopen(efile,"w") : NULL; if(!strcmp(ofile,"-")) { ofile=NULL; fpout = stdout; } else { fpout= xfopen(ofile,"wb"); } if(!fpout) { fprintf(stderr, "Couldn't open output file!\n"); exit(1); } if(1 /*!m_init()*/) { if(1 /*!b_init()*/) { if(1 /*!l_init()*/) { /*if(!pp_init())*/ { if(!x_init()) { /* if(fperr) fprintf(fperr,"%s\n",copyright); */ if(verbose) logout(ctime(&tim1)); /* Pass 1 */ pc[SEG_ABS]= 0; /* abs addressing */ seg_start(fmode, tbase, dbase, bbase, zbase, 0, relmode); if(relmode) { r_mode(RMODE_RELOC); segment = SEG_TEXT; } else { r_mode(RMODE_ABS); } nolink = no_link; for (i=0; ifname)); if(!er) { er=pass1(); pp_close(); } else { sprintf(out, "Couldn't open source file '%s'!\n", ifile); logout(out); } } if((er=b_depth())) { sprintf(out,"Still %d blocks open at end of file!\n",er); logout(out); } if(tbase & (align-1)) { sprintf(out,"Warning: text segment ($%04x) start address doesn't align to %d!\n", tbase, align); logout(out); } if(dbase & (align-1)) { sprintf(out,"Warning: data segment ($%04x) start address doesn't align to %d!\n", dbase, align); logout(out); } if(bbase & (align-1)) { sprintf(out,"Warning: bss segment ($%04x) start address doesn't align to %d!\n", bbase, align); logout(out); } if(zbase & (align-1)) { sprintf(out,"Warning: zero segment ($%04x) start address doesn't align to %d!\n", zbase, align); logout(out); } if (n65816>0) fmode |= 0x8000; switch(align) { case 1: break; case 2: fmode |= 1; break; case 4: fmode |= 2; break; case 256: fmode |=3; break; } if((!er) && relmode) h_write(fpout, fmode, tlen, dlen, blen, zlen, 0); if(!er) { if(verbose) logout("xAss65: Pass 2:\n"); seg_pass2(); if(!relmode) { r_mode(RMODE_ABS); } else { r_mode(RMODE_RELOC); segment = SEG_TEXT; } er=pass2(); } if(fplab) printllist(fplab); tim2=time(NULL); if(verbose) printstat(); if((!er) && relmode) seg_end(fpout); /* write reloc/label info */ if(fperr) fclose(fperr); if(fplab) fclose(fplab); if(fpout) fclose(fpout); } else { logout("fatal: x: no memory!\n"); } pp_end(); /* } else { logout("fatal: pp: no memory!");*/ } } else { logout("fatal: l: no memory!\n"); } } else { logout("fatal: b: no memory!\n"); } /*m_exit();*/ } else { logout("Not enough memory available!\n"); } if(ner || er) { fprintf(stderr, "Break after %d error%c\n",ner,ner?'s':0); /*unlink();*/ if(ofile) { unlink(ofile); } } free(ifiles); return( (er || ner) ? 1 : 0 ); } static void printstat(void) { logout("Statistics:\n"); sprintf(out," %8d of %8d label used\n",ga_lab(),gm_lab()); logout(out); sprintf(out," %8ld of %8ld byte label-memory used\n",ga_labm(),gm_labm()); logout(out); sprintf(out," %8d of %8d PP-defs used\n",ga_pp(),gm_pp()); logout(out); sprintf(out," %8ld of %8ld byte PP-memory used\n",ga_ppm(),gm_ppm()); logout(out); sprintf(out," %8ld of %8ld byte buffer memory used\n",ga_p1(),gm_p1()); logout(out); sprintf(out," %8d blocks used\n",ga_blk()); logout(out); sprintf(out," %8ld seconds used\n",(long)difftime(tim2,tim1)); logout(out); } int h_length(void) { return 26+o_length(); } #if 0 /* write header for relocatable output format */ int h_write(FILE *fp, int tbase, int tlen, int dbase, int dlen, int bbase, int blen, int zbase, int zlen) { fputc(1, fp); /* version byte */ fputc(0, fp); /* hi address 0 -> no C64 */ fputc("o", fp); fputc("6", fp); fputc("5", fp); fputc(0, fp); /* format version */ fputw(mode, fp); /* file mode */ fputw(tbase,fp); /* text base */ fputw(tlen,fp); /* text length */ fputw(dbase,fp); /* data base */ fputw(dlen,fp); /* data length */ fputw(bbase,fp); /* bss base */ fputw(blen,fp); /* bss length */ fputw(zbase,fp); /* zerop base */ fputw(zlen,fp); /* zerop length */ o_write(fp); return 0; } #endif static int setfext(char *s, char *ext) { int j,i=(int)strlen(s); if(i>MAXLINE-5) return(-1); for(j=i-1;j>=0;j--) { if(s[j]==DIRCHAR) { strcpy(s+i,ext); break; } if(s[j]=='.') { strcpy(s+j,ext); break; } } if(!j) strcpy(s+i,ext); return(0); } /* static char *tmp; static unsigned long tmpz; static unsigned long tmpe; */ static long ga_p1(void) { return(afile->mn.tmpz); } static long gm_p1(void) { return(TMPMEM); } static int pass2(void) { int c,er,l,ll,i,al; Datei datei; signed char *dataseg=NULL; signed char *datap=NULL; memode=0; xmode=0; if((dataseg=malloc(dlen))) { if(!dataseg) { fprintf(stderr, "Couldn't alloc dataseg memory...\n"); exit(1); } datap=dataseg; } filep=&datei; afile->mn.tmpe=0L; while(ner<20 && afile->mn.tmpemn.tmpz) { l=afile->mn.tmp[afile->mn.tmpe++]; ll=l; if(!l) { if(afile->mn.tmp[afile->mn.tmpe]==T_LINE) { datei.fline=(afile->mn.tmp[afile->mn.tmpe+1]&255)+(afile->mn.tmp[afile->mn.tmpe+2]<<8); afile->mn.tmpe+=3; } else if(afile->mn.tmp[afile->mn.tmpe]==T_FILE) { datei.fline=(afile->mn.tmp[afile->mn.tmpe+1]&255)+(afile->mn.tmp[afile->mn.tmpe+2]<<8); memcpy(&datei.fname, afile->mn.tmp+afile->mn.tmpe+3, sizeof(datei.fname)); afile->mn.tmpe+=3+sizeof(datei.fname); /* datei.fname = malloc(strlen((char*) afile->mn.tmp+afile->mn.tmpe+3)+1); if(!datei.fname) { fprintf(stderr,"Oops, no more memory\n"); exit(1); } strcpy(datei.fname,(char*) afile->mn.tmp+afile->mn.tmpe+3); afile->mn.tmpe+=3+strlen(datei.fname); */ } } else { /* do not attempt address mode optimization on pass 2 */ er=t_p2(afile->mn.tmp+afile->mn.tmpe,&ll,1,&al); if(er==E_NOLINE) { } else if(er==E_OK) { if(segmentmn.tmp[afile->mn.tmpe+i]); } else if (segment==SEG_DATA && datap) { memcpy(datap,afile->mn.tmp+afile->mn.tmpe,ll); datap+=ll; } } else if(er==E_DSB) { c=afile->mn.tmp[afile->mn.tmpe]; if(segmentmn.tmp[afile->mn.tmpe]);*/ for(i=0;imn.tmpe; /* fprintf(stderr, "ok, ready to insert\n"); for (i=0; imn.tmp[afile->mn.tmpe+i]); } */ offset = afile->mn.tmp[i] + (afile->mn.tmp[i+1] << 8) + (afile->mn.tmp[i+2] << 16); fstart = afile->mn.tmp[i+3] + 1 + (afile->mn.tmp[i+4] << 8); /* usually redundant but here for single-char names that get interpreted as chars */ flen = afile->mn.tmp[i+5]; if (flen > 1) fstart++; /* now fstart points either to string past quote and length mark, OR, single char byte */ /* fprintf(stderr, "offset = %i length = %i fstart = %i flen = %i charo = %c\n", offset, ll, fstart, flen, afile->mn.tmp[afile->mn.tmpe+fstart]); */ /* there is a race condition here where altering the file between validation in t_p2 (xat.c) and here will cause problems. I'm not going to worry about this right now. */ for(j=0; jmn.tmp[i+fstart+j]; } binfnam[flen] = '\0'; /* fprintf(stderr, "fnam = %s\n", binfnam); */ /* primitive insurance */ if (!(foo = fopen(binfnam, "r"))) { errout(E_FNF); ner++; } else { fseek(foo, offset, SEEK_SET); for(j=0; jmn.tmpe+=abs(l); } if(relmode) { if((ll=fwrite(dataseg, 1, dlen, fpout))mn.tmpz); */ } if(er!=E_EOF) { errout(er); } /* { int i; printf("Pass 1 \n"); for(i=0;imn.tmpz;i++) fprintf(stderr, " %02x",255 & afile->mn.tmp[i]); getchar();} */ return(ner); } static void usage(int default816, FILE *fp) { fprintf(fp, "Usage: %s [options] file\n" "Cross-assembler for 65xx/R65C02/65816\n" "\n", programname); fprintf(fp, " -v verbose output\n" " -x old filename behaviour (overrides `-o', `-e', `-l')\n" " This is deprecated and may disappear in future versions!\n" " -C no CMOS-opcodes\n" " -W no 65816-opcodes%s\n" " -w allow 65816-opcodes%s\n", default816 ? "" : " (default)", default816 ? " (default)" : ""); fprintf(fp, " -B show lines with block open/close\n" " -c produce `o65' object instead of executable files (i.e. don't link)\n" " -o filename sets output filename, default is `a.o65'\n" " A filename of `-' sets stdout as output file\n"); fprintf(fp, " -e filename sets errorlog filename, default is none\n" " -l filename sets labellist filename, default is none\n" " -r adds crossreference list to labellist (if `-l' given)\n" " -M allow ``:'' to appear in comments for MASM compatibility\n" " -R start assembler in relocating mode\n"); fprintf(fp, " -Llabel defines `label' as absolute, undefined label even when linking\n" " -b? addr set segment base address to integer value addr\n" " `?' stands for t(ext), d(ata), b(ss) and z(ero) segment\n" " (address can be given more than once, last one is used)\n"); fprintf(fp, " -A addr make text segment start at an address that when the _file_\n" " starts at addr, relocation is not necessary. Overrides -bt\n" " Other segments must be specified with `-b?'\n" " -G suppress list of exported globals\n"); fprintf(fp, " -DDEF=TEXT defines a preprocessor replacement\n" " -Ocharset set output charset (PETSCII or ASCII), case-sensitive\n" " -Idir add directory `dir' to include path (before XAINPUT)\n" " --version output version information and exit\n" " --help display this help and exit\n"); } /* static char *ertxt[] = { "Syntax","Label definiert", "Label nicht definiert","Labeltabelle voll", "Label erwartet","Speicher voll","Illegaler Opcode", "Falsche Adressierungsart","Branch ausserhalb des Bereichs", "Ueberlauf","Division durch Null","Pseudo-Opcode erwartet", "Block-Stack-Ueberlauf","Datei nicht gefunden", "End of File","Block-Struktur nicht abgeschlossen", "NoBlk","NoKey","NoLine","OKDef","DSB","NewLine", "NewFile","CMOS-Befehl","pp:Falsche Anzahl Parameter" }; */ static char *ertxt[] = { "Syntax", "Label already defined", "Label not defined", "Label table full", "Label expected", "Out of memory", "Illegal opcode", "Wrong addressing mode", "Branch out of range", "Overflow", "Division by zero", "Pseudo-opcode expected", "Block stack overflow", "File not found", "End of file", "Unmatched block close", "NoBlk", "NoKey", "NoLine", "OKDef", "DSB", "NewLine", "NewFile", "CMOS instruction used with -C", "pp:Wrong parameter count", "Illegal pointer arithmetic", "Illegal segment", "File header option too long", "File option not at file start (when ROM-able)", "Illegal align value", "65816 mode used/required", "Exceeded recursion limit for label evaluation", "Unresolved preprocessor directive at end of file", "Data underflow", "Illegal quantity", ".bin", /* placeholders for future fatal errors */ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", /* warnings */ "Cutting word relocation in byte value", "Byte relocation in word value", "Illegal pointer arithmetic", "Address access to low or high byte pointer", "High byte access to low byte pointer", "Low byte access to high byte pointer", "Can't optimize forward-defined label; using absolute addressing", "Open preprocessor directive at end of file (intentional?)", "Included binary data exceeds 64KB", "Included binary data exceeds 16MB", "MVN/MVP $XXXX syntax is deprecated and will be removed", /* more placeholders */ "", "", }; static int gl; static int gf; static int x_init(void) { return 0; #if 0 int er=0; /*er=m_alloc(TMPMEM,&tmp);*/ afile->mn.tmp=malloc(TMPMEM); if(!afile->mn.tmp) er=E_NOMEM; afile->mn.tmpz=0L; return(er); #endif } static int puttmp(int c) { int er=E_NOMEM; /*printf("puttmp: afile=%p, tmp=%p, tmpz=%d\n",afile, afile?afile->mn.tmp:0, afile?afile->mn.tmpz:0);*/ if(afile->mn.tmpzmn.tmp[afile->mn.tmpz++]=c; er=E_OK; } return(er); } static int puttmps(signed char *s, int l) { int i=0,er=E_NOMEM; if(afile->mn.tmpz+lmn.tmp[afile->mn.tmpz++]=s[i++]; er=E_OK; } return(er); } static char l[MAXLINE]; static int xa_getline(char *s) { static int ec; static int i,c; int hkfl,j,comcom; j=hkfl=comcom=0; ec=E_OK; if(!gl) { do { ec=pgetline(l); i=0; while(l[i]==' ') i++; while(l[i]!='\0' && isdigit(l[i])) i++; gf=1; if(ec==E_NEWLINE) { puttmp(0); puttmp(T_LINE); puttmp((filep->fline)&255); puttmp(((filep->fline)>>8)&255); ec=E_OK; } else if(ec==E_NEWFILE) { puttmp(0); puttmp(T_FILE); puttmp((filep->fline)&255); puttmp(((filep->fline)>>8)&255); puttmps((signed char*)&(filep->fname), sizeof(filep->fname)); /* puttmps((signed char*)filep->fname, 1+(int)strlen(filep->fname)); */ ec=E_OK; } } while(!ec && l[i]=='\0'); } gl=0; if(!ec || ec==E_EOF) { do { c=s[j]=l[i++]; if (!(hkfl&2) && c=='\"') hkfl^=1; if (!comcom && !(hkfl&1) && c=='\'') hkfl^=2; if (c==';' && !hkfl) comcom = 1; if (c=='\0') break; /* hkfl = comcom = 0 */ if (c==':' && !hkfl && (!comcom || !masm)) { gl=1; break; } j++; } while (c!='\0' && jalign)?a:align; } static void lineout(void) { if(gf) { logout(filep->flinep); logout("\n"); gf=0; } } void errout(int er) { if (er<-ANZERR || er>-1) { if(er>=-(ANZERR+ANZWARN) && er < -ANZERR) { sprintf(out,"%s:line %d: %04x: Warning - %s\n", filep->fname, filep->fline, pc[segment], ertxt[(-er)-1]); } else { /* sprintf(out,"%s:Zeile %d: %04x:Unbekannter Fehler Nr.: %d\n",*/ sprintf(out,"%s:line %d: %04x: Unknown error # %d\n", filep->fname,filep->fline,pc[segment],er); ner++; } } else { if (er==E_NODEF) sprintf(out,"%s:line %d: %04x:Label '%s' not defined\n", filep->fname,filep->fline,pc[segment],lz); else sprintf(out,"%s:line %d: %04x:%s error\n", filep->fname,filep->fline,pc[segment],ertxt[(-er)-1]); ner++; } logout(out); } static void chrput(int c) { /* printf(" %02x",c&255);*/ putc( c&0x00ff,fpout); } void logout(char *s) { fprintf(stderr, "%s",s); if(fperr) fprintf(fperr,"%s",s); } xa-2.3.8/src/xa.h0000600000031500000010000000260011032606131012775 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __XA65_XA_H__ #define __XA65_XA_H__ #include "xah.h" /* For SEG_MAX */ extern int ncmos, cmosfl, w65816, n65816; extern int masm, nolink; extern int noglob; extern int showblk; extern int relmode; extern int crossref; extern char altppchar; extern int tlen, tbase; extern int blen, bbase; extern int dlen, dbase; extern int zlen, zbase; extern int romable, romaddr; extern int memode,xmode; extern int segment; extern int pc[SEG_MAX]; int h_length(void); void set_align(int align_value); void errout(int er); void logout(char *s); #endif /*__XA65_XA_H__ */ xa-2.3.8/src/xaa.c0000600000031500000010000001407111025122566013145 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * Preprocessing arithmetic module * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include "xah.h" #include "xad.h" #include "xar.h" #include "xa.h" #include "xal.h" #include "xaa.h" #include "xat.h" static int pr[]= { P_START,P_ADD,P_ADD,P_MULT,P_MULT,P_SHIFT,P_SHIFT,P_CMP, P_CMP,P_EQU,P_CMP,P_CMP,P_EQU,P_AND,P_XOR,P_OR, P_LAND,P_LOR }; static int pp,pcc; static int fundef; static int ag_term(signed char*,int,int*,int*,int*); static int get_op(signed char*,int*); static int do_op(int*,int,int); /* s = string, v = variable */ int a_term(signed char *s, int *v, int *l, int xpc, int *pfl, int *label, int f) { int er=E_OK; int afl = 0, bfl; *pfl = 0; fundef = f; pp=0; pcc=xpc; if(s[0]=='<') { pp++; er=ag_term(s,P_START,v,&afl, label); bfl = afl & (A_MASK>>8); if( bfl && (bfl != (A_ADR>>8)) && (bfl != (A_LOW>>8)) ) { /*fprintf(stderr,"low byte relocation for a high byte - won't work!\n");*/ errout(W_LOWACC); } if(afl) *pfl=A_LOW | ((afl<<8) & A_FMASK); *v = *v & 255; } else if(s[pp]=='>') { pp++; er=ag_term(s,P_START,v,&afl, label); bfl = afl & (A_MASK>>8); if( bfl && (bfl != (A_ADR>>8)) && (bfl != (A_HIGH>>8)) ) { /*fprintf(stderr,"high byte relocation for a low byte - won't work!\n");*/ errout(W_HIGHACC); } if(afl) *pfl=A_HIGH | ((afl<<8) & A_FMASK) | (*v & 255); *v=(*v>>8)&255; } else { er=ag_term(s,P_START,v,&afl, label); bfl = afl & (A_MASK>>8); if(bfl && (bfl != (A_ADR>>8)) ) { /*fprintf(stderr,"address relocation for a low or high byte - won't work!\n");*/ errout(W_ADDRACC); } if(afl) *pfl = A_ADR | ((afl<<8) & A_FMASK); } *l=pp; /* printf("a_term: afl->%04x *pfl=%04x, (pc=%04x)\n",afl,*pfl, xpc); */ return(er); } static int ag_term(signed char *s, int p, int *v, int *nafl, int *label) { int er=E_OK,o,w,mf=1,afl; afl = 0; /*printf("ag_term(%02x %02x %02x %02x %02x %02x\n",s[0],s[1],s[2],s[3],s[4],s[5]);*/ while(s[pp]=='-') { pp++; mf=-mf; } if(s[pp]=='(') { pp++; if(!(er=ag_term(s,P_START,v,&afl,label))) { if(s[pp]!=')') er=E_SYNTAX; else pp++; } } else if(s[pp]==T_LABEL) { er=l_get(cval(s+pp+1),v, &afl); /* printf("label: er=%d, seg=%d, afl=%d, nolink=%d, fundef=%d\n", er, segment, afl, nolink, fundef); */ if(er==E_NODEF && segment != SEG_ABS && fundef ) { if( nolink || (afl==SEG_UNDEF)) { er = E_OK; *v = 0; afl = SEG_UNDEF; *label = cval(s+pp+1); } } pp+=3; } else if(s[pp]==T_VALUE) { *v=lval(s+pp+1); pp+=4; /* printf("value: v=%04x\n",*v); */ } else if(s[pp]==T_POINTER) { afl = s[pp+1]; *v=cval(s+pp+2); pp+=4; /* printf("pointer: v=%04x, afl=%04x\n",*v,afl); */ } else if(s[pp]=='*') { *v=pcc; pp++; afl = segment; } else { er=E_SYNTAX; } *v *= mf; while(!er && s[pp]!=')' && s[pp]!=']' && s[pp]!=',' && s[pp]!=T_END) { er=get_op(s,&o); if(!er && pr[o]>p) { pp+=1; if(!(er=ag_term(s,pr[o],&w, nafl, label))) { if(afl || *nafl) { /* check pointer arithmetic */ if((afl == *nafl) && (afl!=SEG_UNDEF) && o==2) { afl = 0; /* substract two pointers */ } else if(((afl && !*nafl) || (*nafl && !afl)) && o==1) { afl=(afl | *nafl); /* add constant to pointer */ } else if((afl && !*nafl) && o==2) { afl=(afl | *nafl); /* substract constant from pointer */ } else { if(segment!=SEG_ABS) { if(!dsb_len) { er=E_ILLPOINTER; } } afl=0; } } if(!er) er=do_op(v,w,o); } } else { break; } } *nafl = afl; return(er); } static int get_op(signed char *s, int *o) { int er; *o=s[pp]; if(*o<1 || *o>17) er=E_SYNTAX; else er=E_OK; return(er); } static int do_op(int *w,int w2,int o) { int er=E_OK; switch (o) { case 1: *w +=w2; break; case 2: *w -=w2; break; case 3: *w *=w2; break; case 4: if (w!=0) *w /=w2; else er =E_DIV; break; case 5: *w >>=w2; break; case 6: *w <<=w2; break; case 7: *w = *ww2; break; case 9: *w = *w==w2; break; case 10: *w = *w<=w2; break; case 11: *w = *w>=w2; break; case 12: *w = *w!=w2; break; case 13: *w &=w2; break; case 14: *w ^=w2; break; case 15: *w |=w2; break; case 16: *w =*w&&w2; break; case 17: *w =*w||w2; break; } return(er); } xa-2.3.8/src/xaa.h0000600000031500000010000000203707615405421013155 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __XA65_XAA_H__ #define __XA65_XAA_H__ /* f = 0 -> label must exist; f = 1 -> SEG_UNDEF entry */ int a_term(signed char *s, int *v, int *l, int xpc, int *afl, int *label, int f); #endif /* __XA65_XAA_H__ */ xa-2.3.8/src/xacharset.c0000644000031500000010000000566411143330246014373 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 Andre Fachat (a.fachat@physik.tu-chemnitz.de) * Maintained by Cameron Kaiser * * Charset conversion module * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "xacharset.h" static signed char (*convert_func)(signed char); static signed char convert_char_ascii(signed char c) { return c; } /* * PETSCII conversion roughly follows the PETSCII to UNICODE * mapping at http://www.df.lth.se/~triad/krad/recode/petscii_c64en_lc.txt * linked from wikipedia http://en.wikipedia.org/wiki/PETSCII */ static signed char convert_char_petscii(signed char c) { if (c >= 0x41 && c < 0x5b) { return c + 0x20; } if (c >= 0x61 && c < 0x7b) { return c - 0x20; } if (c == 0x7f) { return 0x14; } return c; } /* * Built upon Steve Judd's suggested PETSCII -> screen code algorithm * This could probably be written a lot better, but it works. * http://www.floodgap.com/retrobits/ckb/display.cgi?572 */ static signed char convert_char_petscreen(signed char c) { int i; i = (int)convert_char_petscii(c); #ifdef SIGH fprintf(stderr, "input: %i output: %i\n", c, i); #endif if (i< 0) i += 0x80; i ^= 0xe0; #ifdef SIGH fprintf(stderr, "(1)input: %i output: %i\n", c, i); #endif i += 0x20; i &= 0xff; #ifdef SIGH fprintf(stderr, "(2)input: %i output: %i\n", c, i); #endif if (i < 0x80) return (signed char)i; i += 0x40; i &= 0xff; #ifdef SIGH fprintf(stderr, "(3)input: %i output: %i\n", c, i); #endif if (i < 0x80) return (signed char)i; i ^= 0xa0; #ifdef SIGH fprintf(stderr, "(4)input: %i output: %i\n", c, i); #endif return (signed char)i; } static signed char convert_char_high(signed char c) { return (c | 0x80); } typedef struct { char *name; signed char (*func)(signed char); } charset; static charset charsets[] = { { "ASCII", convert_char_ascii }, { "PETSCII", convert_char_petscii }, { "PETSCREEN", convert_char_petscreen }, { "HIGH", convert_char_high }, { NULL, NULL } }; int set_charset(char *charset_name) { int i = 0; while (charsets[i].name != NULL) { if (strcmp(charsets[i].name, charset_name) == 0) { convert_func = charsets[i].func; return 0; } i++; } return -1; } signed char convert_char(signed char c) { return convert_func(c); } xa-2.3.8/src/xacharset.h0000644000031500000010000000223010546754740014401 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-2006 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __XA65_XA_CHARSET_H__ #define __XA65_XA_CHARSET_H__ /* set the target character set the chars - values in quotes - should be converted to returns 0 on success and -1 when the name is not found */ int set_charset(char *charset_name); /* convert a char */ signed char convert_char(signed char c); #endif /*__XA65_XA_H__ */ xa-2.3.8/src/xad.h0000644000031500000010000000265007615405421013171 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __XA65_XAD_H__ #define __XA65_XAD_H__ #ifndef abs #define abs(a) (a >= 0) ? a : -a #endif #define hashcode(n, l) (n[0] & 0x0f) | (((l - 1) ? (n[1] & 0x0f) : 0) << 4) #define fputw(a, fp) do { \ fputc(a & 255, fp); \ fputc((a >> 8) & 255, fp); \ } while (0) #define cval(s) 256 * ((s)[1] & 255) + ((s)[0]&255) #define lval(s) 65536 * ((s)[2] & 255) + 256 * ((s)[1] & 255) + ((s)[0] & 255) #define wval(i, v) do { \ t[i++] = T_VALUE; \ t[i++] = v & 255; \ t[i++] = (v >> 8) & 255; \ t[i++] = (v >> 16) & 255; \ } while (0) #endif /* __XA65_XAD_H__ */ xa-2.3.8/src/xah.h0000600000031500000010000001371012447607622013172 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * Maintained by Cameron Kaiser * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __XA65_XAH_H__ #define __XA65_XAH_H__ #define ANZLAB 5000 /* mal 14 -> Byte */ #define LABMEM 40000L #define MAXLAB 32 #define MAXBLK 16 #define MAXFILE 7 #define MAXLINE 2048 #define MAXPP 40000L #define ANZDEF 2340 /* mal 14 -> Byte, ANZDEF * 14 < 32768 */ #define TMPMEM 200000L /* Zwischenspeicher von Pass1 nach Pass 2 */ typedef struct LabOcc { struct LabOcc *next; int line; char *fname; } LabOcc; typedef struct { int blk; int val; int len; int fl; /* 0 = label value not valid/known, * 1 = label value known */ int afl; /* 0 = no address (no relocation), 1 = address label */ int nextindex; char *n; struct LabOcc *occlist; } Labtab; typedef struct { char *search; int s_len; char *replace; int p_anz; int nextindex; } List; #define MEMLEN (4 + TMPMEM + MAXPP + LABMEM + \ (long)(sizeof (Labtab) * ANZLAB) + \ (long)(sizeof (List) * ANZDEF)) #define DIRCHAR '/' #define DIRCSTRING "/" /* for Atari: #define DIRCHAR '\\' #define DIRCSTRING "\\" */ #define BUFSIZE 4096 /* File-Puffegroesse (wg Festplatte) */ #define E_OK 0 /* Fehlernummern */ #define E_SYNTAX -1 /* Syntax Fehler */ #define E_LABDEF -2 /* Label definiert */ #define E_NODEF -3 /* Label nicht definiert */ #define E_LABFULL -4 /* Labeltabelle voll */ #define E_LABEXP -5 /* Label erwartet */ #define E_NOMEM -6 /* kein Speicher mehr */ #define E_ILLCODE -7 /* Illegaler Opcode */ #define E_ADRESS -8 /* Illegale Adressierung */ #define E_RANGE -9 /* Branch out of range */ #define E_OVERFLOW -10 /* Ueberlauf */ #define E_DIV -11 /* Division durch Null */ #define E_PSOEXP -12 /* Pseudo-Opcode erwartet */ #define E_BLKOVR -13 /* Block-Stack Uebergelaufen */ #define E_FNF -14 /* File not found (pp) */ #define E_EOF -15 /* End of File */ #define E_BLOCK -16 /* Block inkonsistent */ #define E_NOBLK -17 #define E_NOKEY -18 #define E_NOLINE -19 #define E_OKDEF -20 /* okdef */ #define E_DSB -21 #define E_NEWLINE -22 #define E_NEWFILE -23 #define E_CMOS -24 #define E_ANZPAR -25 #define E_ILLPOINTER -26 /* illegal pointer arithmetic! */ #define E_ILLSEGMENT -27 /* illegal pointer arithmetic! */ #define E_OPTLEN -28 /* file header option too long */ #define E_ROMOPT -29 /* header option not directly after * file start in romable mode */ #define E_ILLALIGN -30 /* illegal align value */ #define E_65816 -31 #define E_ORECMAC -32 /* exceeded recursion limit for label eval */ #define E_OPENPP -33 /* open preprocessor directive */ #define E_OUTOFDATA -34 /* out of data */ #define E_ILLQUANT -35 /* generic illegal quantity error */ #define E_BIN -36 /* okdef */ /* errors thru 64 are placeholders available for use */ #define W_ADRRELOC -65 /* word relocation in byte value */ #define W_BYTRELOC -66 /* byte relocation in word value */ #define E_WPOINTER -67 /* illegal pointer arithmetic! */ #define W_ADDRACC -68 /* addr access to low or high byte pointer */ #define W_HIGHACC -69 /* high byte access to low byte pointer */ #define W_LOWACC -70 /* low byte access to high byte pointer */ #define W_FORLAB -71 /* no zp-optimization for a forward label */ #define W_OPENPP -72 /* warning about open preprocessor directive */ #define W_OVER64K -73 /* included binary over 64K in 6502 mode */ #define W_OVER16M -74 /* included binary over 16M in 65816 mode */ #define W_OLDMVNS -75 /* use of old mv? $xxxx syntax */ /* warnings 76-77 are placeholders available for use */ #define T_VALUE -1 #define T_LABEL -2 #define T_OP -3 #define T_END -4 #define T_LINE -5 #define T_FILE -6 #define T_POINTER -7 #define P_START 0 /* Prioritaeten fuer Arithmetik */ #define P_LOR 1 /* Von zwei Operationen wird immer */ #define P_LAND 2 /* die mit der hoeheren Prioritaet */ #define P_OR 3 /* zuerst ausgefuehrt */ #define P_XOR 4 #define P_AND 5 #define P_EQU 6 #define P_CMP 7 #define P_SHIFT 8 #define P_ADD 9 #define P_MULT 10 #define P_INV 11 #define A_ADR 0x8000 /* all are or'd with (afl = segment type)<<8 */ #define A_HIGH 0x4000 /* or'd with the low byte */ #define A_LOW 0x2000 #define A_MASK 0xe000 /* reloc type mask */ #define A_FMASK 0x0f00 /* segment type mask */ #define A_LONG 0xc000 #define FM_OBJ 0x1000 #define FM_SIZE 0x2000 #define FM_RELOC 0x4000 #define FM_CPU 0x8000 #define SEG_ABS 0 #define SEG_UNDEF 1 #define SEG_TEXT 2 #define SEG_DATA 3 #define SEG_BSS 4 #define SEG_ZERO 5 #define SEG_MAX 6 typedef struct Fopt { signed char *text; /* text after pass1 */ int len; } Fopt; typedef struct relocateInfo { int next; int adr; int afl; int lab; } relocateInfo; typedef struct File { int fmode; int slen; int relmode; int old_abspc; int base[SEG_MAX]; int len[SEG_MAX]; struct { signed char *tmp; unsigned long tmpz; unsigned long tmpe; } mn; struct { int *ulist; int un; int um; } ud; struct { relocateInfo *rlist; int mlist; int nlist; int first; } rt; struct { relocateInfo *rlist; int mlist; int nlist; int first; } rd; struct { Fopt *olist; int mlist; int nlist; } fo; struct { int hashindex[256]; Labtab *lt; int lti; int ltm; } la; } File; extern File *afile; #endif /* __XA65_XAH_H__ */ xa-2.3.8/src/xah2.h0000600000031500000010000000200607615405421013242 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __XA65_XAH2_H__ #define __XA65_XAH2_H__ typedef struct { char *fname; /* fname[MAXLINE]; */ int fline; int bdepth; FILE *filep; char *flinep; } Datei; #endif /* __XA65_XAH2_H__ */ xa-2.3.8/src/xal.c0000600000031500000010000002555110405053352013162 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * Label management module (also see xau.c) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include /* structs and defs */ #include "xad.h" #include "xah.h" #include "xar.h" #include "xah2.h" #include "xap.h" #include "xa.h" /* externals */ #include "xam.h" #include "xal.h" /* exported globals */ char *lz; /* local prototypes */ static int b_fget(int*,int); static int b_ltest(int,int); static int b_get(int*); static int b_test(int); static int ll_def(char *s, int *n, int b); /* local variables */ /* static int hashindex[256]; static Labtab *lt = NULL; static int lti = 0; static int ltm = 0; */ /* static char *ln; static unsigned long lni; static long sl; */ static Labtab *ltp; int l_init(void) { return 0; #if 0 int er; for(er=0;er<256;er++) hashindex[er]=0; /*sl=(long)sizeof(Labtab);*/ /* if(!(er=m_alloc((long)(sizeof(Labtab)*ANZLAB),(char**)<))) er=m_alloc((long)LABMEM,&ln);*/ er=m_alloc((long)(sizeof(Labtab)*ANZLAB),(char**)<); lti=0; /* lni=0L;*/ return(er); #endif } int ga_lab(void) { return(afile->la.lti); } int gm_lab(void) { return(ANZLAB); } long gm_labm(void) { return((long)LABMEM); } long ga_labm(void) { return(0 /*lni*/); } void printllist(fp) FILE *fp; { int i; LabOcc *p; char *fname = NULL; for(i=0;ila.lti;i++) { ltp=afile->la.lt+i; fprintf(fp,"%s, 0x%04x, %d, 0x%04x\n",ltp->n,ltp->val,ltp->blk, ltp->afl); p = ltp->occlist; if(p) { while(p) { if(fname != p->fname) { if(p!=ltp->occlist) fprintf(fp,"\n"); fprintf(fp," %s",p->fname); fname=p->fname; } fprintf(fp," %d", p->line); p=p->next; } fprintf(fp,"\n"); } fname=NULL; } } int lg_set(char *s ) { int n, er; er = ll_search(s,&n); if(er==E_OK) { fprintf(stderr,"Warning: global label doubly defined!\n"); } else { if(!(er=ll_def(s,&n,0))) { ltp=afile->la.lt+n; ltp->fl=2; ltp->afl=SEG_UNDEF; } } return er; } int l_def(char *s, int *l, int *x, int *f) { int n,er,b,i=0; *f=0; b=0; n=0; if(s[0]=='-') { *f+=1; i++; } else if(s[0]=='+') { i++; n++; b=0; } while(s[i]=='&') { n=0; i++; b++; } if(!n) b_fget(&b,b); if(!isalpha(s[i]) && s[i]!='_') er=E_SYNTAX; else { er=ll_search(s+i,&n); if(er==E_OK) { ltp=afile->la.lt+n; if(*f) { *l=ltp->len+i; } else if(ltp->fl==0) { *l=ltp->len+i; if(b_ltest(ltp->blk,b)) er=E_LABDEF; else ltp->blk=b; } else er=E_LABDEF; } else if(er==E_NODEF) { if(!(er=ll_def(s+i,&n,b))) /* ll_def(...,*f) */ { ltp=afile->la.lt+n; *l=ltp->len+i; ltp->fl=0; } } *x=n; } return(er); } int l_search(char *s, int *l, int *x, int *v, int *afl) { int n,er,b; *afl=0; er=ll_search(s,&n); /*printf("l_search: lab=%s(l=%d), afl=%d, er=%d, n=%d\n",s,*l, *afl,er,n);*/ if(er==E_OK) { ltp=afile->la.lt+n; *l=ltp->len; if(ltp->fl == 1) { l_get(n,v,afl);/* *v=lt[n].val;*/ *x=n; } else { er=E_NODEF; lz=ltp->n; *x=n; } } else { b_get(&b); er=ll_def(s,x,b); /* ll_def(...,*v); */ ltp=afile->la.lt+(*x); *l=ltp->len; if(!er) { er=E_NODEF; lz=ltp->n; } } return(er); } int l_vget(int n, int *v, char **s) { ltp=afile->la.lt+n; (*v)=ltp->val; *s=ltp->n; return 0; } void l_addocc(int n, int *v, int *afl) { LabOcc *p, *pp; (void)v; /* quench warning */ (void)afl; /* quench warning */ ltp = afile->la.lt+n; pp=NULL; p = ltp->occlist; while(p) { if (p->line == filep->fline && p->fname == filep->fname) return; pp = p; p = p->next; } p = malloc(sizeof(LabOcc)); if(!p) { fprintf(stderr,"Oops, out of memory!\n"); exit(1); } p->next = NULL; p->line = filep->fline; p->fname = filep->fname; if(pp) { pp->next = p; } else { ltp->occlist = p; } } int l_get(int n, int *v, int *afl) { if(crossref) l_addocc(n,v,afl); ltp=afile->la.lt+n; (*v)=ltp->val; lz=ltp->n; *afl = ltp->afl; /*printf("l_get('%s'(%d), v=$%04x, afl=%d, fl=%d\n",ltp->n, n, *v, *afl, ltp->fl);*/ return( (ltp->fl==1) ? E_OK : E_NODEF); } void l_set(int n, int v, int afl) { ltp=afile->la.lt+n; ltp->val = v; ltp->fl = 1; ltp->afl = afl; /*printf("l_set('%s'(%d), v=$%04x, afl=%d\n",ltp->n, n, v, afl);*/ } static void ll_exblk(int a, int b) { int i; for (i=0;ila.lti;i++) { ltp=afile->la.lt+i; if((!ltp->fl) && (ltp->blk==a)) ltp->blk=b; } } static int ll_def(char *s, int *n, int b) /* definiert naechstes Label nr->n */ { int j=0,er=E_NOMEM,hash; char *s2; /*printf("ll_def: s=%s\n",s); */ if(!afile->la.lt) { afile->la.lti = 0; afile->la.ltm = 1000; afile->la.lt = malloc(afile->la.ltm * sizeof(Labtab)); } if(afile->la.lti>=afile->la.ltm) { afile->la.ltm *= 1.5; afile->la.lt = realloc(afile->la.lt, afile->la.ltm * sizeof(Labtab)); } if(!afile->la.lt) { fprintf(stderr, "Oops: no memory!\n"); exit(1); } #if 0 if((ltila.lt+afile->la.lti; /* s2=ltp->n=ln+lni; while((jlen=j; ltp->n = s2; ltp->blk=b; ltp->fl=0; ltp->afl=0; ltp->occlist=NULL; hash=hashcode(s,j); ltp->nextindex=afile->la.hashindex[hash]; afile->la.hashindex[hash]=afile->la.lti; *n=afile->la.lti; afile->la.lti++; /* lni+=j+1;*/ /* } } */ /*printf("ll_def return: %d\n",er);*/ return(er); } int ll_search(char *s, int *n) /* search Label in Tabelle ,nr->n */ { int i,j=0,k,er=E_NODEF,hash; while(s[j] && (isalnum(s[j])||(s[j]=='_'))) j++; hash=hashcode(s,j); i=afile->la.hashindex[hash]; /*printf("search?\n");*/ if(i>=afile->la.ltm) return E_NODEF; do { ltp=afile->la.lt+i; if(j==ltp->len) { for (k=0;(kn[k]==s[k]);k++); if((j==k)&&(!b_test(ltp->blk))) { er=E_OK; break; } } if(!i) break; i=ltp->nextindex; }while(1); *n=i; #if 0 if(er!=E_OK && er!=E_NODEF) { fprintf(stderr, "Fehler in ll_search:er=%d\n",er); getchar(); } #endif return(er); } int ll_pdef(char *t) { int n; if(ll_search(t,&n)==E_OK) { ltp=afile->la.lt+n; if(ltp->fl) return(E_OK); } return(E_NODEF); } int l_write(FILE *fp) { int i, afl, n=0; if(noglob) { fputc(0, fp); fputc(0, fp); return 0; } for (i=0;ila.lti;i++) { ltp=afile->la.lt+i; if((!ltp->blk) && (ltp->fl==1)) { n++; } } fputc(n&255, fp); fputc((n>>8)&255, fp); for (i=0;ila.lti;i++) { ltp=afile->la.lt+i; if((!ltp->blk) && (ltp->fl==1)) { fprintf(fp, "%s",ltp->n); fputc(0,fp); afl = ltp->afl; /* hack to switch undef and abs flag from internal to file format */ /*printf("label %s, afl=%04x, A_FMASK>>8=%04x\n", ltp->n, afl, A_FMASK>>8);*/ if( (afl & (A_FMASK>>8)) < SEG_TEXT) afl^=1; fputc(afl,fp); fputc(ltp->val&255, fp); fputc((ltp->val>>8)&255, fp); } } /*fputc(0,fp);*/ return 0; } static int bt[MAXBLK]; static int blk; static int bi; int b_init(void) { blk =0; bi =0; bt[bi]=blk; return(E_OK); } int b_depth(void) { return bi; } int ga_blk(void) { return(blk); } int b_open(void) { int er=E_BLKOVR; if(bi=0) *n=bt[bi-i]; else *n=0; return(E_OK); } static int b_test(int n) { int i=bi; while( i>=0 && n!=bt[i] ) i--; return( i+1 ? E_OK : E_NOBLK ); } static int b_ltest(int a, int b) /* testet ob bt^-1(b) in intervall [0,bt^-1(a)] */ { int i=0,er=E_OK; if(a!=b) { er=E_OK; while(i<=bi && b!=bt[i]) { if(bt[i]==a) { er=E_NOBLK; break; } i++; } } return(er); } xa-2.3.8/src/xal.h0000600000031500000010000000272107615405421013170 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __XA65_XAL_H__ #define __XA65_XAL_H__ #include /* for FILE */ extern char *lz; int l_init(void); int ga_lab(void); int gm_lab(void); long gm_labm(void); long ga_labm(void); int lg_set(char *); int b_init(void); int b_depth(void); void printllist(FILE *fp); int ga_blk(void); int l_def(char *s, int* l, int *x, int *f); int l_search(char *s, int *l, int *x, int *v, int *afl); void l_set(int n, int v, int afl); int l_get(int n, int *v, int *afl); int l_vget(int n, int *v, char **s); int ll_search(char *s, int *n); int ll_pdef(char *t); int b_open(void); int b_close(void); int l_write(FILE *fp); #endif /* __XA65_XAL_H__ */ xa-2.3.8/src/xam.c0000600000031500000010000000723010405052751013157 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * Memory manager/malloc() stub module * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include "xah.h" /* structs */ static int ninc = 0; static char **nip = NULL; void reg_include(char *path) { char **nip2; if(path && *path) { nip2 = realloc(nip,sizeof(char*)*(ninc+1)); if(nip2) { nip = nip2; nip[ninc++] = path; } else { fprintf(stderr,"Warning: couldn' alloc mem (reg_include)\n"); } } } FILE *xfopen(const char *fn,const char *mode) { FILE *file; char c,*cp,n[MAXLINE],path[MAXLINE]; char xname[MAXLINE], n2[MAXLINE]; int i,l=(int)strlen(fn); if(l>=MAXLINE) { fprintf(stderr,"filename '%s' too long!\n",fn); return NULL; } for(i=0;i #include #include #include "xah.h" #include "xar.h" #include "xa.h" #include "xat.h" #include "xao.h" /* static Fopt *olist =NULL; static int mlist =0; static int nlist =0; */ /* sets file option after pass 1 */ void set_fopt(int l, signed char *buf, int reallen) { /*printf("set_fopt(%s, l=%d\n",buf,l);*/ while(afile->fo.mlist<=afile->fo.nlist) { afile->fo.mlist +=5; afile->fo.olist = realloc(afile->fo.olist, afile->fo.mlist*sizeof(Fopt)); if(!afile->fo.olist) { fprintf(stderr, "Fatal: Couldn't alloc memory (%lu bytes) for fopt list!\n", (unsigned long)( afile->fo.mlist*sizeof(Fopt))); exit(1); } } afile->fo.olist[afile->fo.nlist].text=malloc(l); if(!afile->fo.olist[afile->fo.nlist].text) { fprintf(stderr, "Fatal: Couldn't alloc memory (%d bytes) for fopt!\n",l); exit(1); } memcpy(afile->fo.olist[afile->fo.nlist].text, buf, l); afile->fo.olist[afile->fo.nlist++].len = reallen; } /* writes file options to a file */ void o_write(FILE *fp) { int i,j,l,afl; signed char *t; for(i=0;ifo.nlist;i++) { l=afile->fo.olist[i].len; t=afile->fo.olist[i].text; /* do not optimize */ t_p2(t, &l, 1, &afl); if(l>254) { errout(E_OPTLEN); } else { fputc((l+1)&0xff,fp); } for(j=0;jfo.nlist;i++) { free(afile->fo.olist[i].text); } free(afile->fo.olist); afile->fo.olist = NULL; afile->fo.nlist = 0; afile->fo.mlist = 0; } size_t o_length(void) { int i; size_t n = 0; for(i=0;ifo.nlist;i++) { /*printf("found option: %s, len=%d, n=%d\n", afile->fo.olist[i].text, afile->fo.olist[i].len,n);*/ n += afile->fo.olist[i].len +1; } return ++n; } xa-2.3.8/src/xao.h0000600000031500000010000000215307615405421013172 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __XA65_XAO_H__ #define __XA65_XAO_H__ /* sets file option after pass 1 */ void set_fopt(int l, signed char *buf, int reallen); /* writes file options to a file */ void o_write(FILE *fp); /* return overall length of header options */ size_t o_length(void); #endif /* __XA65_XAO_H__ */ xa-2.3.8/src/xap.c0000600000031500000010000006261012447416254013177 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * Maintained by Cameron Kaiser * * File handling and preprocessor (also see xaa.c) module * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #ifndef _MSC_VER #include #endif #include "xad.h" #include "xah.h" #include "xah2.h" #include "xar.h" #include "xa.h" #include "xam.h" #include "xal.h" #include "xat.h" #include "xap.h" /* define this for recursive evaluation output */ /* #define DEBUG_RECMAC */ char s[MAXLINE]; Datei *filep; static int tcompare(char*,char**,int); static int pp_replace(char*,char*,int,int); static int searchdef(char*); static int fgetline(char*,int len, int *rlen, FILE*); static int icl_open(char*),pp_ifdef(char*),pp_ifndef(char*); static int pp_else(char*),pp_endif(char*); static int pp_echo(char*),pp_if(char*),pp_print(char*),pp_prdef(char*); static int pp_ifldef(char*),pp_iflused(char*); static int pp_undef(char*); #define ANZBEF 13 #define VALBEF 6 static int ungeteof = 0; static char *cmd[]={ "echo","include","define","undef","printdef","print", "ifdef","ifndef","else","endif", "ifldef","iflused","if" }; static int (*func[])(char*) = { pp_echo,icl_open,pp_define,pp_undef, pp_prdef,pp_print, pp_ifdef,pp_ifndef, pp_else,pp_endif, pp_ifldef,pp_iflused,pp_if }; static char *mem; static unsigned long memfre; static int nlf; static int nff; static int hashindex[256]; static List *liste; static unsigned int rlist; static int fsp; static int loopfl; static Datei flist[MAXFILE+1]; static char in_line[MAXLINE]; int pp_comand(char *t) { int i,l,er=1; i=tcompare(t,cmd,ANZBEF); if(i>=0) { if(loopfl && (i>1; return(0); } /* stub for handling CPP directives */ int pp_cpp(char *t) { char name[MAXLINE]; if(sscanf(t, " %d \"%s\"", &filep->fline, name) == 2) { /* massage it into our parameters and drop last quote */ char *u; filep->fline--; if((u = (char *)strrchr(name, '"'))) *u = '\0'; free(filep->fname); filep->fname = strdup(name); if(!filep->fname) { fprintf(stderr,"Oops, no more memory!\n"); exit(1); } return (0); } else { return(E_SYNTAX); } } /* pp_undef is a great hack to get it working fast... */ int pp_undef(char *t) { int i; if((i=searchdef(t))) { i+=rlist; liste[i].s_len=0; } return 0; } int pp_prdef(char *t) { char *x; int i,j; if((i=searchdef(t))) { i+=rlist; x=liste[i].search; sprintf(s,"\n%s",x); if(liste[i].p_anz) { sprintf(s+strlen(s),"("); for(j=0;j=ANZDEF || memfre=ANZDEF || memfre10) errout(E_ORECMAC); } (void)strcpy(liste[rlist+i].replace, nfto); #ifdef DEBUG_RECMAC printf("FINAL: -%s=%s\n",liste[rlist+i].search,liste[rlist+i].replace); #endif } if(!er) er=pp_replace(fto,fti,rlist,rlist+i); /* if(flag) printf("sl=%d,",sl);*/ sl=(int)((long)y+1L-(long)t); /* if(flag) printf("sl=%d\n",sl);*/ rs=fto; /* printf("->%s\n",fto);*/ } } if(er) return(er); } d=(int)strlen(rs)-sl; if(strlen(to)+d>=MAXLINE) return(E_NOMEM); /* if(d<0) { y=t+sl+d; x=t+sl; while(*y++=*x++); } if(d>0) { for(ll=strlen(t);ll>=sl;ll--) t[ll+d]=t[ll]; } */ if(d) (void)strcpy(t+sl+d,ti+sl); i=0; while((c=rs[i])) t[i++]=c; l=sl+d;/*=0;*/ break; } } if(!n) break; n=liste[n].nextindex; } while(1); } else { for(n=b-1;n>=a;n--) { sl=liste[n].s_len; if(sl && (sl==l)) { i=0; x=liste[n].search; while(t[i]==*x++ && t[i]) i++; if(i==sl) { rs=liste[n].replace; if(liste[n].p_anz) { (void)strcpy(fti,liste[n].replace); if(rlist+liste[n].p_anz>=ANZDEF || memfre=MAXLINE) return(E_NOMEM); /* if(d<0) { y=t+sl+d; x=t+sl; while(*y++=*x++); } if(d>0) { for(ll=strlen(t);ll>=sl;ll--) t[ll+d]=t[ll]; } */ if(d) (void)strcpy(t+sl+d,ti+sl); i=0; while((c=rs[i])) t[i++]=c; l+=d;/*0;*/ break; } } } } ti+=ld; t+=l; } } return(E_OK); } int pp_init(void) { int er; for(er=0;er<256;er++) hashindex[er]=0; fsp=0; er=0; mem=malloc(MAXPP); if(!mem) er=E_NOMEM; memfre=MAXPP; rlist=0; nlf=1; nff=1; if(!er) { liste=malloc((long)ANZDEF*sizeof(List)); if(!liste) er=E_NOMEM; } return(er); } int pp_open(char *name) { FILE *fp; fp=xfopen(name,"r"); /* we have to alloc it dynamically to make the name survive another pp_open - it's used in the cross-reference list */ flist[0].fname = malloc(strlen(name)+1); if(!flist[0].fname) { fprintf(stderr,"Oops, no more memory!\n"); exit(1); } (void)strcpy(flist[0].fname,name); flist[0].fline=0; flist[0].bdepth=b_depth(); flist[0].filep=fp; flist[0].flinep=NULL; return(((long)fp)==0l); } void pp_close(void) { if(flist[fsp].bdepth != b_depth()) { fprintf(stderr, "Blocks not consistent in file %s: start depth=%d, end depth=%d\n", flist[fsp].fname, flist[fsp].bdepth, b_depth()); } fclose(flist[fsp].filep); } void pp_end(void) { } Datei *pp_getidat(void) { return &flist[fsp]; } int icl_close(int *c) { *c='\n'; if(!fsp) return(E_EOF); if(flist[fsp].bdepth != b_depth()) { fprintf(stderr, "Blocks not consistent in file %s: start depth=%d, end depth=%d\n", flist[fsp].fname, flist[fsp].bdepth, b_depth()); } fclose(flist[fsp--].filep); nff=1; return(E_OK); } int icl_open(char *tt) { FILE *fp2; int j,i=0; pp_replace(s,tt,-1,rlist); if(fsp>=MAXFILE) return(-1); if(s[i]=='<' || s[i]=='"') i++; for(j=i;s[j];j++) if(s[j]=='>' || s[j]=='"') s[j]='\0'; fp2=xfopen(s+i,"r"); if(!fp2) return(E_FNF); setvbuf(fp2,NULL,_IOFBF,BUFSIZE); fsp++; /* we have to alloc it dynamically to make the name survive another pp_open - it's used in the cross-reference list */ flist[fsp].fname = malloc(strlen(s+i)+1); if(!flist[fsp].fname) { fprintf(stderr,"Oops, no more memory!\n"); exit(1); } strcpy(flist[fsp].fname,s+i); flist[fsp].fline=0; flist[fsp].bdepth=b_depth(); flist[fsp].flinep=NULL; flist[fsp].filep=fp2; nff=1; return(0); } int pgetline(char *t) { int c,er=E_OK; int rlen, tlen; char *p = 0; loopfl =0; /* set if additional fetch needed */ filep =flist+fsp; do { c=fgetline(in_line, MAXLINE, &rlen, flist[fsp].filep); /* continuation lines */ tlen = rlen; while(c=='\n' && tlen && in_line[tlen-1]=='\\') { c=fgetline(in_line + tlen-1, MAXLINE-tlen, &rlen, flist[fsp].filep); tlen += rlen-1; } if(in_line[0]=='#' || in_line[0] == altppchar) { if (in_line[1]==' ') { /* cpp comment -- pp_comand doesn't handle this right */ er=pp_cpp(in_line+1); } else { if((er=pp_comand(in_line+1))) { if(er!=1) { logout(in_line); logout("\n"); } } } } else er=1; if(c==EOF) { if (loopfl && fsp) { char bletch[MAXLINE]; sprintf(bletch, "at end of included file %s:\n", flist[fsp].fname); logout(bletch); errout(W_OPENPP); } er=icl_close(&c); } } while(!er || (loopfl && er!=E_EOF)); if (loopfl) { errout(E_OPENPP); } /* handle the double-slash comment (like in C++) */ p = strchr(in_line, '/'); if (p != NULL) { if (p[1] == '/') { *p = 0; /* terminate string */ } } if(!er || loopfl) { in_line[0]='\0'; } er= (er==1) ? E_OK : er ; if(!er) er=pp_replace(t,in_line,-1,rlist); if(!er && nff) er=E_NEWFILE; if(!er && nlf) er=E_NEWLINE; nlf=nff=0; filep=flist+fsp; filep->flinep=in_line; return(er); } /*************************************************************************/ /* this is the most disgusting code I have ever written, but Andre drove me to it because I can't think of any other F$%Y#*U(%&Y##^#KING way to fix the last line bug ... a very irritated Cameron */ /* however, it also solved the problem of open #ifdefs not bugging out */ /* #define DEBUG_EGETC */ int egetc(FILE *fp) { int c; c = getc(fp); if (c == EOF) { if (ungeteof) { #ifdef DEBUG_EGETC fprintf(stderr, "eof claimed\n"); #endif return c; } else { #ifdef DEBUG_EGETC fprintf(stderr, "got eof!!\n"); #endif ungeteof = 1; return '\n'; } } ungeteof = 0; return c; } /* smart getc that can skip C comment blocks */ int rgetc(FILE *fp) { static int c,d,fl; fl=0; do { while((c=egetc(fp))==13); /* remove ^M for unices */ if(fl && (c=='*')) { if((d=egetc(fp))!='/') ungetc(d,fp); else { fl--; while((c=egetc(fp))==13); } } if(c=='\n') { flist[fsp].fline++; nlf=1; } else if(c=='/') { if((d=egetc(fp))!='*') ungetc(d,fp); else fl++; } } while(fl && (c!=EOF)); return(c-'\t'?c:' '); } int fgetline(char *t, int len, int *rlen, FILE *fp) { static int c,i; i=0; do { c=rgetc(fp); if(c==EOF || c=='\n') { t[i]='\0'; break; } t[i]=c; i= (i #include #include "xad.h" #include "xah.h" #include "xar.h" #include "xa.h" #include "xal.h" #include "xao.h" #include "xau.h" File *afile = NULL; int rmode = RMODE_RELOC; int r_set(int pc, int afl, int l) { /*printf("set relocation @$%04x, l=%d, afl=%04x, segment=%d\n",pc, l, afl,segment);*/ if(segment==SEG_TEXT) return rt_set(pc,afl,l,0); if(segment==SEG_DATA) return rd_set(pc,afl,l,0); return 0; } int u_set(int pc, int afl, int label, int l) { /*printf("set relocation @$%04x, l=%d, afl=%04x, segment=%d, label=%d\n", pc, l, afl,segment, label);*/ if((afl & A_FMASK) == (SEG_UNDEF<<8)) label = u_label(label); /* set label as undefined */ if(segment==SEG_TEXT) return rt_set(pc,afl,l,label); if(segment==SEG_DATA) return rd_set(pc,afl,l,label); return 0; } void r_mode(int m) { static int old_segment = SEG_TEXT; /*printf("setting mode to %s\n",(m==RMODE_RELOC)?"reloc":"abs");*/ if(rmode!=m) { if(m==RMODE_RELOC) { segment = old_segment; } else { /* absolute mode */ old_segment = segment; segment = SEG_ABS; } } rmode = m; } int rt_set(int pc, int afl, int l, int lab) { int p,pp; if(!rmode) return 0; /*printf("set relocation @$%04x, l=%d, afl=%04x\n",pc, l, afl);*/ if(l==2 && ((afl & A_MASK)!=A_ADR)) { errout(W_BYTRELOC); /*printf("Warning: byte relocation in word value at PC=$%04x!\n",pc);*/ } if(l==1 && ((afl&A_MASK)==A_ADR)) { if((afl & A_FMASK) != (SEG_ZERO<<8)) { /*printf("afl=%04x\n",afl);*/ errout(W_ADRRELOC); } /*printf("Warning: cutting address relocation in byte value at PC=$%04x!\n",pc);*/ afl = (afl & (~A_MASK)) | A_LOW; } if(afile->rt.nlist>=afile->rt.mlist) { afile->rt.mlist+=500; afile->rt.rlist=realloc(afile->rt.rlist, afile->rt.mlist*sizeof(relocateInfo)); } if(!afile->rt.rlist) { fprintf(stderr, "Oops: no memory for relocation table!\n"); exit(1); } afile->rt.rlist[afile->rt.nlist].adr = pc; afile->rt.rlist[afile->rt.nlist].afl = afl; afile->rt.rlist[afile->rt.nlist].lab = lab; afile->rt.rlist[afile->rt.nlist].next= -1; /* sorting this into the list is not optimized, to be honest... */ if(afile->rt.first<0) { afile->rt.first = afile->rt.nlist; } else { p=afile->rt.first; pp=-1; while(afile->rt.rlist[p].adrrt.rlist[p].next>=0) { pp=p; p=afile->rt.rlist[p].next; } /* printf("endloop: p=%d(%04x), pp=%d(%04x), nlist=%d(%04x)\n", p,p<0?0:afile->rt.rlist[p].adr,pp,pp<0?0:afile->rt.rlist[pp].adr,afile->rt.nlist,afile->rt.nlist<0?0:afile->rt.rlist[afile->rt.nlist].adr); */ if(afile->rt.rlist[p].next<0 && afile->rt.rlist[p].adrrt.rlist[p].next=afile->rt.nlist; } else if(pp==-1) { afile->rt.rlist[afile->rt.nlist].next = afile->rt.first; afile->rt.first = afile->rt.nlist; } else { afile->rt.rlist[afile->rt.nlist].next = p; afile->rt.rlist[pp].next = afile->rt.nlist; } } afile->rt.nlist++; return 0; } int rt_write(FILE *fp, int pc) { int p=afile->rt.first; int pc2, afl; while(p>=0) { pc2=afile->rt.rlist[p].adr; afl=afile->rt.rlist[p].afl; /* hack to switch undef and abs flag from internal to file format */ if( ((afl & A_FMASK)>>8) < SEG_TEXT) afl^=0x100; /*printf("rt_write: pc=%04x, pc2=%04x, afl=%x\n",pc,pc2,afl);*/ if((pc2-pc) < 0) { fprintf(stderr, "Oops, negative offset!\n"); } else { while((pc2-pc)>254) { fputc(255,fp); pc+=254; } fputc(pc2-pc, fp); pc=pc2; fputc((afl>>8)&255, fp); if((afile->rt.rlist[p].afl&A_FMASK)==(SEG_UNDEF<<8)) { fputc(afile->rt.rlist[p].lab & 255, fp); fputc((afile->rt.rlist[p].lab>>8) & 255, fp); } if((afl&A_MASK)==A_HIGH) fputc(afl&255,fp); } p=afile->rt.rlist[p].next; } fputc(0, fp); free(afile->rt.rlist); afile->rt.rlist = NULL; afile->rt.mlist = afile->rt.nlist = 0; afile->rt.first = -1; return 0; } void seg_start(int fmode, int t_base, int d_base, int b_base, int z_base, int slen, int relmode) { afile->fmode = fmode; afile->slen = slen; afile->relmode = relmode; pc[SEG_TEXT] = afile->base[SEG_TEXT] = t_base; pc[SEG_DATA] = afile->base[SEG_DATA] = d_base; pc[SEG_BSS] = afile->base[SEG_BSS] = b_base; pc[SEG_ZERO] = afile->base[SEG_ZERO] = z_base; afile->old_abspc = pc[SEG_ABS]; pc[SEG_ABS] = pc[SEG_TEXT]; } File *alloc_file(void) { File *afile; int i; afile = malloc(sizeof(File)); if(!afile) { fprintf(stderr,"Oops: not enough memory!\n"); exit(1); } afile->mn.tmp = malloc(TMPMEM); if(!afile->mn.tmp) { fprintf(stderr,"Oops: not enough memory!\n"); exit(1); } afile->mn.tmpz = 0; afile->mn.tmpe = 0; afile->ud.ulist = NULL; afile->ud.un = afile->ud.um = 0; afile->rt.rlist = NULL; afile->rt.first = -1; afile->rt.mlist = afile->rt.nlist = 0; afile->rd.rlist = NULL; afile->rd.first = -1; afile->rd.mlist = afile->rd.nlist = 0; afile->fo.olist = NULL; afile->fo.mlist = afile->fo.nlist = 0; for(i=0;i<256;i++) afile->la.hashindex[i]=0; afile->la.lt = NULL; afile->la.lti = 0; afile->la.ltm = 0; afile->len[SEG_TEXT] = afile->len[SEG_DATA] = afile->len[SEG_BSS] = afile->len[SEG_ZERO] = 0; return afile; } void seg_pass2(void) { pc[SEG_TEXT] = afile->base[SEG_TEXT]; pc[SEG_DATA] = afile->base[SEG_DATA]; pc[SEG_BSS] = afile->base[SEG_BSS]; pc[SEG_ZERO] = afile->base[SEG_ZERO]; afile->old_abspc = pc[SEG_ABS]; pc[SEG_ABS] = pc[SEG_TEXT]; } void seg_end(FILE *fpout) { #if 0 afile->len[SEG_TEXT] = pc[SEG_TEXT] - afile->base[SEG_TEXT]; afile->len[SEG_DATA] = pc[SEG_DATA] - afile->base[SEG_DATA]; afile->len[SEG_BSS ] = pc[SEG_BSS ] - afile->base[SEG_BSS ]; afile->len[SEG_ZERO] = pc[SEG_ZERO] - afile->base[SEG_ZERO]; #endif /* TODO: file length to embed */ /* pc[SEG_ABS] = afile->old_abspc + seg_flen();*/ /*printf("seg_end: len[text]=%d, len[data]=%d, len[bss]=%d, len[zero]=%d\n", afile->len[SEG_TEXT], afile->len[SEG_DATA], afile->len[SEG_BSS], afile->len[SEG_ZERO]);*/ segment = SEG_ABS; u_write(fpout); rt_write(fpout, afile->base[SEG_TEXT]-1); rd_write(fpout, afile->base[SEG_DATA]-1); l_write(fpout); } /* write header for relocatable output format */ int h_write(FILE *fp, int mode, int tlen, int dlen, int blen, int zlen, int stack) { afile->len[SEG_TEXT] = tlen; afile->len[SEG_DATA] = dlen; afile->len[SEG_BSS ] = blen; afile->len[SEG_ZERO] = zlen; fputc(1, fp); /* version byte */ fputc(0, fp); /* hi address 0 -> no C64 */ fputc('o', fp); fputc('6', fp); fputc('5', fp); fputc(0, fp); /* format version */ fputw(mode, fp); /* file mode */ fputw(afile->base[SEG_TEXT],fp); /* text base */ fputw(tlen,fp); /* text length */ fputw(afile->base[SEG_DATA],fp); /* data base */ fputw(dlen,fp); /* data length */ fputw(afile->base[SEG_BSS],fp); /* bss base */ fputw(blen,fp); /* bss length */ fputw(afile->base[SEG_ZERO],fp); /* zerop base */ fputw(zlen,fp); /* zerop length */ fputw(stack,fp); /* needed stack size */ o_write(fp); return 0; } xa-2.3.8/src/xar.h0000600000031500000010000000304510404750315013171 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __XA65_XAR_H__ #define __XA65_XAR_H__ #define RMODE_ABS 0 #define RMODE_RELOC 1 extern File *alloc_file(void); /* jumps to r[td]_set, depending on segment */ int r_set(int pc, int reloc, int len); int u_set(int pc, int reloc, int label, int len); int rt_set(int pc, int reloc, int len, int label); int rd_set(int pc, int reloc, int len, int label); int rt_write(FILE *fp, int pc); int rd_write(FILE *fp, int pc); void r_mode(int mode); /* int rmode; */ int h_write(FILE *fp, int mode, int tlen, int dlen, int blen, int zlen, int stacklen); void seg_start(int fmode, int tbase, int dbase, int bbase, int zbase, int stacklen, int relmode); void seg_end(FILE *); void seg_pass2(void); #endif /* __XA65_XAR_H__ */ xa-2.3.8/src/xar2.c0000600000031500000010000000752007615407766013273 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "xah.h" #include "xa.h" #include "xar.h" /* static relocateInfo *rlist = NULL; static int mlist = 0, nlist = 0; static int first = -1; */ /* int rmode; */ int rd_set(int pc, int afl, int l, int lab) { int p,pp; /* if(!rmode) return 0; */ /*printf("set relocation @$%04x, l=%d, afl=%04x\n",pc, l, afl);*/ if(l==2 && ((afl & A_MASK)!=A_ADR)) { errout(W_BYTRELOC); /*printf("Warning: byte relocation in word value at PC=$%04x!\n",pc);*/ } if(l==1 && ((afl&A_MASK)==A_ADR)) { if((afl & A_FMASK) != (SEG_ZERO<<8)) errout(W_ADRRELOC); /*printf("Warning: cutting address relocation in byte value at PC=$%04x!\n",pc);*/ afl = (afl & (~A_MASK)) | A_LOW; } if(afile->rd.nlist>=afile->rd.mlist) { afile->rd.mlist+=500; afile->rd.rlist=realloc(afile->rd.rlist, afile->rd.mlist*sizeof(relocateInfo)); } if(!afile->rd.rlist) { fprintf(stderr, "Oops: no memory for relocation table!\n"); exit(1); } afile->rd.rlist[afile->rd.nlist].adr = pc; afile->rd.rlist[afile->rd.nlist].afl = afl; afile->rd.rlist[afile->rd.nlist].lab = lab; afile->rd.rlist[afile->rd.nlist].next= -1; /* sorting this into the list is not optimized, to be honest... */ if(afile->rd.first<0) { afile->rd.first = afile->rd.nlist; } else { p=afile->rd.first; pp=-1; while(afile->rd.rlist[p].adrrd.rlist[p].next>=0) { pp=p; p=afile->rd.rlist[p].next; } /* printf("endloop: p=%d(%04x), pp=%d(%04x), nlist=%d(%04x)\n", p,p<0?0:afile->rd.rlist[p].adr,pp,pp<0?0:afile->rd.rlist[pp].adr,afile->rd.nlist,afile->rd.nlist<0?0:afile->rd.rlist[afile->rd.nlist].adr); */ if(afile->rd.rlist[p].next<0 && afile->rd.rlist[p].adrrd.rlist[p].next=afile->rd.nlist; } else if(pp==-1) { afile->rd.rlist[afile->rd.nlist].next = afile->rd.first; afile->rd.first = afile->rd.nlist; } else { afile->rd.rlist[afile->rd.nlist].next = p; afile->rd.rlist[pp].next = afile->rd.nlist; } } afile->rd.nlist++; return 0; } int rd_write(FILE *fp, int pc) { int p=afile->rd.first; int pc2, afl; while(p>=0) { pc2=afile->rd.rlist[p].adr; afl=afile->rd.rlist[p].afl; /*printf("rd_write: pc=%04x, pc2=%04x, afl=%x\n",pc,pc2,afl);*/ /* hack to switch undef and abs flag from internal to file format */ if( ((afl & A_FMASK)>>8) < SEG_TEXT) afl^=0x100; if((pc2-pc) < 0) { fprintf(stderr, "Oops, negative offset!\n"); } else { while((pc2-pc)>254) { fputc(255,fp); pc+=254; } fputc(pc2-pc, fp); pc=pc2; fputc((afl>>8)&255, fp); if((afile->rd.rlist[p].afl&A_FMASK)==(SEG_UNDEF<<8)) { fputc(afile->rd.rlist[p].lab & 255, fp); fputc((afile->rd.rlist[p].lab>>8) & 255, fp); } if((afl&A_MASK)==A_HIGH) fputc(afl&255,fp); } p=afile->rd.rlist[p].next; } fputc(0, fp); free(afile->rd.rlist); afile->rd.rlist = NULL; afile->rd.mlist = afile->rd.nlist = 0; afile->rd.first = -1; return 0; } xa-2.3.8/src/xat.c0000600000031500000010000021413712447663320013204 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * maintained by Cameron Kaiser * * Core tokenizing module/pass 1 and pass 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* enable this to turn on (copious) optimization output */ /* #define DEBUG_AM */ #include #include #include "xad.h" #include "xah.h" #include "xah2.h" #include "xar.h" #include "xa.h" #include "xaa.h" #include "xal.h" #include "xat.h" #include "xao.h" #include "xap.h" #include "xacharset.h" int dsb_len = 0; static int t_conv(signed char*,signed char*,int*,int,int*,int*,int*,int,int*); static int t_keyword(signed char*,int*,int*); static int tg_asc(signed char*,signed char*,int*,int*,int*,int*,int); static void tg_dez(signed char*,int*,int*); static void tg_hex(signed char*,int*,int*); static void tg_oct(signed char*,int*,int*); static void tg_bin(signed char*,int*,int*); /* assembly mnemonics and pseudo-op tokens */ /* ina and dea don't work yet */ static char *kt[] ={ /* 1 2 3 4 5 6 7 8 9 10 */ "adc","and","asl","bbr","bbs","bcc","bcs","beq","bit","bmi", "bne","bpl","bra","brk","bvc","bvs","brl","clc","cld","cli", /* "clv","cmp","cpx","cpy","cop","dea","dec","dex","dey","eor", */ "clv","cmp","cpx","cpy","cop",/*"dea",*/"dec","dex","dey","eor", /* "ina","inc","inx","iny","jmp","jsr","lda","ldx","ldy","lsr", */ /*"ina",*/"inc","inx","iny","jmp","jsr","lda","ldx","ldy","lsr", "mvp","mvn","nop","ora","pha","php","phx","phy","pla","plp", "plx","ply","phb","phd","phk","plb","pld","pea","pei","per", "rmb","rol","ror","rti","rts","rep","rtl","sbc","sec","sed", "sei","smb","sta","stx","sty","stz","sep","stp","tax","tay", "trb","tsb","tsx","txa","txs","tya","txy","tyx","tcd","tdc", "tcs","tsc","wai","wdb","xba","xce", ".byt",".word",".asc",".dsb", ".(", ".)", "*=", ".text",".data",".bss", ".zero",".fopt", ".byte", ".end", ".list", ".xlist", ".dupb", ".blkb", ".db", ".dw", ".align",".block", ".bend",".al",".as",".xl",".xs", ".bin", ".aasc" }; static int lp[]= { 0,1,1,1,1,2,2,1,1,1,2,2,2,1,1,1,2,2 }; /* mvn and mvp are handled specially, they have a weird syntax */ #define Kmvp 38 #define Kmvn Kmvp+1 /* index into token array for pseudo-ops */ /* last valid mnemonic */ #define Lastbef 93 /* last valid token+1 */ #define Anzkey 123 #define Kbyt Lastbef+1 #define Kword Lastbef+2 #define Kasc Lastbef+3 #define Kdsb Lastbef+4 #define Kopen Lastbef+5 /* .( */ #define Kclose Lastbef+6 /* .) */ #define Kpcdef Lastbef+7 /* *=value */ #define Ktext Lastbef+8 #define Kdata Lastbef+9 #define Kbss Lastbef+10 #define Kzero Lastbef+11 #define Kfopt Lastbef+12 #define Kbyte Lastbef+13 /* gets remapped to Kbyt */ #define Kend Lastbef+14 /* ignored (MASM compat.) */ #define Klist Lastbef+15 /* ignored (MASM compat.) */ #define Kxlist Lastbef+16 /* ignored (MASM compat.) */ #define Kdupb Lastbef+17 /* gets remapped to Kdsb */ #define Kblkb Lastbef+18 /* gets remapped to Kdsb */ #define Kdb Lastbef+19 /* gets remapped to Kbyt */ #define Kdw Lastbef+20 /* gets remapped to Kword */ #define Kalign Lastbef+21 #define Kblock Lastbef+22 /* gets remapped to .( */ #define Kbend Lastbef+23 /* gets remapped to .) */ #define Kalong Lastbef+24 #define Kashort Lastbef+25 #define Kxlong Lastbef+26 #define Kxshort Lastbef+27 #define Kbin Lastbef+28 #define Kaasc Lastbef+29 #define Kreloc Anzkey /* *= (relocation mode) */ #define Ksegment Anzkey+1 /* array used for hashing tokens (26 entries, a-z) */ static int ktp[]={ 0,3,17,25,28,29,29,29,29,32,34,34,38,40,41,42,58, 58,65,76,90,90,90,92,94,94,94,Anzkey }; #define Admodes 24 /* * opcodes for each addressing mode * high byte: supported architecture (no bits = original NMOS 6502) * bit 1: R65C02 * bit 2: 65816 * bit 3: 65816 and allows 16-bit quantity (immediate only) * low byte: opcode itself * * each opcode is indexed in this order: *=65816, ^=R65C02 * 00 = implied * 01 = zero page * 02 = zero page,x * 03 = direct page,y* * 04 = direct page (indirect)* * 05 = (indirect,x) * 06 = (indirect),y * 07 = immediate (8-bit) * 08 = absolute * 09 = absolute,x * 10 = absolute,y * 11 = relative * 12 = (indirect-16) i.e., jmp (some_vector) * 13 = (absolute,x)* * 14 = zero page+relative test'n'branch ^ * 15 = zero page clear'n'set'bit ^ * 16 = relative long* * 17 = absolute long* * 18 = absolute long,x* * 19 = stack relative* * 20 = stack relative (indirect),y* * 21 = direct page (indirect long)* * 22 = direct page (indirect long),y* * 23 = (indirect long) */ static int ct[Lastbef+1][Admodes] ={ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 imm */ { -1, 0x65,0x75,-1,0x172,0x61,0x71,0x469,0x6d,0x7d,0x79,-1, -1, -1, -1, -1, -1,0x26f,0x27f,0x263,0x273,0x267,0x277,-1 }, /*adc*/ { -1, 0x25,0x35,-1,0x132,0x21,0x31,0x429,0x2d,0x3d,0x39,-1, -1, -1, -1, -1, -1,0x22f,0x23f,0x223,0x233,0x227,0x237,-1 }, /*and*/ { 0x0a,0x06,0x16,-1, -1, -1, -1, -1, 0x0e,0x1e,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*asl*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x10f,-1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bbr*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x18f,-1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bbs*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x90,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bcc*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0xb0,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bcs*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0xf0,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*beq*/ { -1, 0x24,0x134,-1, -1, -1, -1, 0x589,0x2c,0x13c,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bit*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x30,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bmi*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0xd0,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bne*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x10,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bpl*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x180,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bra*/ { 0x00,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*brk*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x50,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bvc*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0x70,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*bvs*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,0x282, -1, -1, -1, -1, -1, -1, -1 }, /*brl*/ { 0x18,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*clc*/ { 0xd8,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*cld*/ { 0x58,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*cli*/ { 0xb8,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*clv*/ { -1, 0xc5,0xd5,-1, 0x1d2,0xc1,0xd1,0x4c9,0xcd,0xdd,0xd9,-1, -1, -1, -1, -1,-1,0x2cf,0x2df,0x2c3,0x2d3,0x2c7,0x2d7,-1 }, /*cmp*/ { -1, 0xe4,-1, -1, -1, -1, -1, 0x8e0,0xec,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*cpx*/ { -1, 0xc4,-1, -1, -1, -1, -1, 0x8c0,0xcc,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*cpy*/ { -1, -1, -1, -1, -1, -1, -1, 0x202,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*cop*/ /* { 0x13a,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },*/ /*dea*/ { 0x13a,0xc6,0xd6,-1, -1, -1, -1, -1, 0xce,0xde,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*dec*/ { 0xca,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*dex*/ { 0x88,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*dey*/ { -1, 0x45,0x55,-1, 0x152,0x41,0x51,0x449,0x4d,0x5d,0x59,-1, -1, -1, -1, -1,-1,0x24f,0x25f,0x243,0x253,0x247,0x257,-1 }, /*eor*/ /* { 0x11a,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },*/ /*ina*/ { 0x11a,0xe6,0xf6,-1, -1, -1, -1, -1, 0xee,0xfe,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*inc*/ { 0xe8,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*inx*/ { 0xc8,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*iny*/ { -1, -1, -1, -1, -1, -1, -1, -1, 0x4c,-1, -1, -1, 0x6c,0x17c,-1, -1, -1,0x25c, -1, -1, -1, -1, -1,0x2dc}, /*jmp*/ { -1, -1, -1, -1, -1, -1, -1, -1, 0x20,-1, -1, -1, -1, 0x2fc,-1, -1, -1,0x222, -1, -1, -1, -1, -1, -1 }, /*jsr*/ { -1, 0xa5,0xb5,-1, 0x1b2,0xa1,0xb1,0x4a9,0xad,0xbd,0xb9,-1, -1, -1, -1, -1,-1,0x2af,0x2bf,0x2a3,0x2b3,0x2a7,0x2b7,-1 }, /*lda*/ { -1, 0xa6,-1, 0xb6,-1, -1, -1, 0x8a2,0xae,-1, 0xbe,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*ldx*/ { -1, 0xa4,0xb4,-1, -1, -1, -1, 0x8a0,0xac,0xbc,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*ldy*/ { 0x4a,0x46,0x56,-1, -1, -1, -1, -1, 0x4e,0x5e,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*lsr*/ { -1, -1, -1, -1, -1, -1, -1, -1, 0x244,-1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*mvp*/ { -1, -1, -1, -1, -1, -1, -1, -1, 0x254,-1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*mvn*/ { 0xea,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*nop*/ { -1, 0x05,0x15,-1, 0x112,0x01,0x11,0x409,0x0d,0x1d,0x19,-1, -1, -1, -1, -1,-1,0x20f,0x21f,0x203,0x213,0x207,0x217,-1 }, /*ora*/ { 0x48,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*pha*/ { 0x08,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*php*/ { 0x1da,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*phx*/ { 0x15a,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*phy*/ { 0x68,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*pla*/ { 0x28,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*plp*/ { 0x1fa,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*plx*/ { 0x17a,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*ply*/ { 0x28b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*phb*/ { 0x20b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*phd*/ { 0x24b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*phk*/ { 0x2ab,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*plb*/ { 0x22b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*pld*/ { -1, -1, -1, -1, -1, -1, -1, -1, 0x2f4,-1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*pea*/ { -1, -1, -1, -1,0x2d4, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*pei*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, 0x262,-1, -1, -1, -1, -1, -1, -1 }, /*per*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,0x107, -1, -1, -1, -1, -1, -1, -1, -1 }, /*rmb*/ { 0x2a,0x26,0x36,-1, -1, -1, -1, -1, 0x2e,0x3e,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*rol*/ { 0x6a,0x66,0x76,-1, -1, -1, -1, -1, 0x6e,0x7e,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*ror*/ { 0x40,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*rti*/ { 0x60,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*rts*/ { -1, -1, -1, -1, -1, -1, -1, 0x2c2,-1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*rep*/ { 0x26b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*rtl*/ { -1, 0xe5,0xf5,-1, 0x1f2,0xe1,0xf1,0x4e9,0xed,0xfd,0xf9,-1, -1, -1, -1, -1,-1,0x2ef,0x2ff,0x2e3,0x2f3,0x2e7,0x2f7,-1 }, /*sbc*/ { 0x38,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*sec*/ { 0xf8,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*sed*/ { 0x78,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*sei*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,0x187, -1, -1, -1, -1, -1, -1, -1, -1 }, /*smb*/ { -1, 0x85,0x95,-1, 0x192,0x81,0x91,-1, 0x8d,0x9d,0x99,-1, -1, -1, -1, -1,-1,0x28f,0x29f,0x283,0x293,0x287,0x297,-1 }, /*sta*/ { -1, 0x86,-1, 0x96,-1, -1, -1, -1, 0x8e,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*stx*/ { -1, 0x84,0x94,-1, -1, -1, -1, -1, 0x8c,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*sty*/ { -1, 0x164,0x174,-1, -1, -1, -1, -1, 0x19c,0x19e,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*stz*/ { -1, -1, -1, -1, -1, -1, -1, 0x2e2,-1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*sep*/ { 0x2db,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*stp*/ { 0xaa,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tax*/ { 0xa8,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tay*/ { -1, 0x114,-1, -1, -1, -1, -1, -1, 0x11c,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*trb*/ { -1, 0x104,-1, -1, -1, -1, -1, -1, 0x10c,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tsb*/ { 0xba,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tsx*/ { 0x8a,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*txa*/ { 0x9a,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*txs*/ { 0x98,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tya*/ { 0x29b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*txy*/ { 0x2bb,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tyx*/ { 0x25b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tcd*/ { 0x27b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tdc*/ { 0x21b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tcs*/ { 0x23b,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*tsc*/ { 0x2cb,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*wai*/ { 0x242,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*wdb*/ { 0x2eb,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /*xba*/ { 0x2fb,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /*xce*/ } ; #define Syntax 14 #define Maxbyt 4 /* grouped syntaxes. each row = operand type, column = bytes allowed */ static int at[Syntax][Maxbyt] ={ { 0, -1, -1 ,-1 }, /* implied: no operand */ { -1, 7, -1 ,-1 }, /* immediate: single byte operand only */ { -1, 15, -1 ,-1 }, /* relative: single byte operand only */ { -1, -1, 14 ,-1 }, /* test'n'branch: two bytes only */ { -1, 1, 8 ,17 }, /* addressing: 1 byte for zp, 2 for absolute, 3 for absolute long */ { -1, 2, 9 ,18 }, /* ,x: same */ { -1, 3, 10 ,-1 }, /* ,y: 1 byte for dp,y, 2 for absolute,y */ { -1, 4, 12 ,-1 }, /* (indirect): 1 byte for (dp), 2 for (absolute) */ { -1, 5, 13 ,-1 }, /* (i,x): 1 byte for (zp,x), 2 for (a,x) */ { -1, 6, -1 ,-1 }, /* (i),y: 1 byte only */ { -1, 21, 23 ,-1 }, /* (indirect long): 1 byte for (dp), 2 for (a) */ { -1, 22, -1 ,-1 }, /* (indirect long),y: 1 byte only */ { -1, 19, -1 ,-1 }, /* stack relative: 1 byte only */ { -1, 20, -1 ,-1 } /* SR (in),y: 1 byte only */ }; #define AnzAlt 5 /* disambiguation table. for example, arbitrary instruction xxx $0000 could be either interpreted as an absolute operand, or possibly relative. note: does not look at comma or after, if present. */ static int xt[AnzAlt][2] ={ /* Alternativ Adr-Modes */ { 8, 11 }, /* abs -> rel */ { 2, 3 }, /* z,x -> z,y */ { 5, 6 }, /* ,x) -> ),y */ { 9, 10 }, /* a,x -> a,y */ { 8, 16 } /* abs -> relong */ }; /* cross check: instruction should be this many bytes long in total */ /* indexed by addressing mode */ static int le[] ={ 1,2,2,2,2,2,2,2,3,3,3,2,3,3,3,2, /* new modes */ 3,4,4,2,2,2,2,3 }; /* indicates absolute->zp optimizable addressing modes (abs->zp) */ /* indexed by addressing mode */ static int opt[] ={ -1,-1,-1,-1,-1,-1,-1,-1,1,2,3,-1,4,5,-1,-1, /*new*/ -1,8,9,-1,-1,-1,-1,-1 }; /* abs -> zp */ /* pass 1 */ int t_p1(signed char *s, signed char *t, int *ll, int *al) { static int er,l,n,v,nk,na1,na2,bl,am,sy,i,label,byte; /*,j,v2 ;*/ int afl = 0; /* notes and typical conventions ... er = error code am = addressing mode in use */ bl=0; *al = 0; /* printf("\n"); */ /* convert the next token from string s */ #ifdef DEBUG_AM fprintf(stderr, "- p1 %d starting -\n", pc[segment]); #endif er=t_conv(s,t,&l,pc[segment],&nk,&na1,&na2,0,&byte); /* leaving our token sequence in t */ *ll=l; /* printf("t_conv (er=%d):",er); for(i=0;i1) && (t[0]base[SEG_TEXT] = pc[SEG_TEXT] = romaddr + h_length(); romable=1; } if(!er) { /* * * pseudo-op dispatch (except .byt, .asc) * */ n=t[0]; /* TODO: make that a big switch statement... */ /* maybe later. Cameron */ if(n==Kend || n==Klist || n==Kxlist) { *ll = 0; /* ignore */ } else if(n==Kfopt) { if(romable==1) er=E_ROMOPT; t[0] = Kbyt; set_fopt(l,t,nk+1-na1+na2); *ll = 0; } else if(n==Kpcdef) { int tmp; if(!(er=a_term(t+1,&tmp /*&pc[SEG_ABS]*/,&l,pc[segment],&afl,&label,0))) { i=1; wval(i,tmp /*pc[SEG_ABS]*/); t[i++]=T_END; *ll=6; er=E_OKDEF; /*printf("set pc=%04x, oldsegment=%d, pc[segm]=%04x, ", pc[SEG_ABS], segment, pc[segment]); printf(" wrote %02x %02x %02x %02x %02x %02x\n", t[0],t[1],t[2],t[3],t[4],t[5]);*/ if(segment==SEG_TEXT) { pc[SEG_ABS] = tmp; r_mode(RMODE_ABS); } else { if(!relmode) { pc[segment] = tmp; } else { er = E_ILLSEGMENT; } } /*printf("newsegment=%d, pc[ABS]=%04x\n", segment, pc[SEG_ABS]);*/ } else { /* TODO: different error code */ if((segment==SEG_ABS) && (er==E_SYNTAX && l==0)) { /*printf("reloc: oldseg=%d, pc[oldseg]=%04x, pc[abs]=%04x, pc[text]=%04x\n", segment, pc[segment], pc[SEG_ABS], pc[SEG_TEXT]);*/ t[0]=Kreloc; i=1; wval(i,pc[SEG_TEXT]); t[i++]=T_END; *ll=6; er=E_OKDEF; r_mode(RMODE_RELOC); /*printf(" : newseg=%d, pc[newseg]=%04x, pc[abs]=%04x, pc[text]=%04x\n", segment, pc[segment], pc[SEG_ABS], pc[SEG_TEXT]);*/ } } } else if(n==Kopen) { if(showblk) fprintf(stderr, "%s line %d: .(\n", pp_getidat()->fname, pp_getidat()->fline); b_open(); er=E_NOLINE; } else if(n==Kclose) { if(showblk) fprintf(stderr, "%s line %d: .)\n", pp_getidat()->fname, pp_getidat()->fline); er=b_close(); if(!er) er=E_NOLINE; } else if(n==Kalong) { if (!w65816) { er=E_65816; } else { memode=1; t[0]=Kalong; *ll=1; er=E_OKDEF; } } else if(n==Kashort) { memode=0; t[0]=Kashort; *ll=1; er=E_OKDEF; } else if(n==Kxlong) { if (!w65816) { er=E_65816; } else { xmode=1; t[0]=Kxlong; *ll=1; er=E_OKDEF; } } else if(n==Kxshort) { xmode=0; t[0]=Kxshort; *ll=1; er=E_OKDEF; } else if(n==Kdsb) { dsb_len = 1; if(!(er=a_term(t+1,&bl,&l,pc[segment],&afl,&label,0))) { er=E_OKDEF; } dsb_len = 0; } else if(n==Ktext) { /* if(segment!=SEG_ABS) { */ segment = relmode ? SEG_TEXT : SEG_ABS; t[0]=Ksegment; t[1]=segment; *ll=2; er=E_OKDEF; /* } else { er=E_ILLSEGMENT; } */ } else if(n==Kdata) { /* if(segment!=SEG_ABS) { */ segment = SEG_DATA; t[0]=Ksegment; t[1]=SEG_DATA; *ll=2; er=E_OKDEF; /* } else { er=E_ILLSEGMENT; } */ } else if(n==Kbss) { /* if(segment!=SEG_ABS) { */ segment = SEG_BSS; t[0]=Ksegment; t[1]=SEG_BSS; *ll=2; er=E_OKDEF; /* } else { er=E_ILLSEGMENT; } */ } else if(n==Kzero) { /* if(segment!=SEG_ABS) { */ segment = SEG_ZERO; t[0]=Ksegment; t[1]=SEG_ZERO; *ll=2; er=E_OKDEF; /* } else { er=E_ILLSEGMENT; } */ } else if (n==Kbin) { int j; int l; /* this first pass just calculates a prospective length for pass 2. */ char binfnam[255]; int offset; int length; int fstart; i = 1; j = 0; /* get offset */ if(!(er=a_term(t+i,&offset,&l,pc[segment],&afl,&label,1))) { i += l; } if (offset < 0) er = E_ILLQUANT; if(t[i] == ',') { /* skip comma */ i++; } else { er = E_SYNTAX; } /* get length */ if (!er && !(er=a_term(t+i,&length,&l,pc[segment],&afl,&label,1))) { i += l; } if (length < 0) er = E_ILLQUANT; if(t[i] == ',') { /* skip comma */ i++; } else { er = E_SYNTAX; } /* get filename. the tokenizer can either see it as a multichar string ... */ if (!er) { int k; fstart = i; if(t[i]=='\"') { i++; k=t[i]+i+1; i++; while(i 255) er = E_NOMEM; /* buffer overflow */ } binfnam[j] = '\0'; /* or as a 'char' if it's a single character ("word" would have been caught by the above) */ } else if(!(er=a_term(t+i,&v,&l,pc[segment],&afl,&label,1))) { binfnam[0] = v; binfnam[1] = '\0'; i += l; } } /* three arguments only please */ if (!er && t[i] != T_END) { er = E_SYNTAX; } if (!er) { FILE *foo; #ifdef DEBUG_AM fprintf(stderr, "binclude1 offset = %i len = %i filename = %s endchar = %i\n", offset, length, binfnam, i); #endif if (!(foo = fopen(binfnam, "r"))) { er = E_FNF; } else { fseek(foo, 0, SEEK_END); if ((length+offset) > ftell(foo)) { er = E_OUTOFDATA; } else { length = (length) ? length : (ftell(foo)-offset); } fclose(foo); } if (!er) { if (length > 65535 && !w65816) { errout(W_OVER64K); } else if (length > 16777215) { errout(W_OVER16M); } /* pass parameters back to xa.c */ *ll=i+1; /* bl=length+2; */ bl=length; er = E_OKDEF; /* defer to pass 2 */ } } } else if(n==Kalign) { int tmp; if(segment!=SEG_ABS) { if(!(er=a_term(t+1,&tmp,&l,pc[segment],&afl,&label,0))) { if(tmp == 1 || tmp == 2 || tmp == 4 || tmp == 256) { set_align(tmp); if(pc[segment] & (tmp-1)) { /* not aligned */ int tmp2; t[0]=Kdsb; i=1; bl=tmp=(tmp - (pc[segment] & (tmp-1))) & (tmp-1); wval(i,tmp); t[i++]=','; tmp2= 0xea; wval(i,tmp2); /* nop opcode */ t[i++]=T_END; *ll=9; er=E_OKDEF; } else { *ll=0; /* ignore if aligned right */ } } else { er=E_ILLALIGN; } } } else { er=E_ILLSEGMENT; } } else /* optimization okay on pass 1: use 0 for fl */ { #ifdef DEBUG_AM fprintf(stderr, "E_OK ... t_p2 xat.c %i %i\n", t[0], *ll); #endif er=t_p2(t,ll,(0 | byte), al); } } else if(er==E_NODEF) { /* * no label was found from t_conv! * try to figure out most likely length * */ #ifdef DEBUG_AM fprintf(stderr, "E_NODEF pass1 xat.c\n"); #endif er = E_OK; /* stuff error */ n=t[0]; /* look at first token */ /* mnemonic dispatch -- abbreviated form in t_p2, but changed here to not do anything other than 24-bit optimization since we don't know the value of the label */ /* choose addressing mode; add commas found */ if(n>=0 && n<=Lastbef && n != Kmvn && n != Kmvp) /* not for mvn/p */ { if(t[1]==T_END) { sy=0; /* implied */ } else if(t[1]=='#') { sy=1+nk; /* immediate */ } else if(t[1]=='(') { sy=7+nk; /* computed */ } else sy=4+nk; /* absolute or zero page */ /* length counter set to maximum length + 1 */ bl=Maxbyt+1; /* find best fit for length of this operand */ while(--bl) { /* look at syntax table (at) using syntax (sy) as index. is there an addressing mode for an operand of this length? am = addressing mode */ if((am=at[sy][bl-1])>=0) { if(am>Admodes-1) /* no, it's -1, syntax error */ { er=E_SYNTAX; break; } if(ct[n][am]>=0) /* yes, valid token *and* mode, so we're done */ break; /* no valid mode for this token, see if it's something ambiguous; if so, try to interpret in that context. */ for(v=0;v=0) break; if(v=0 && am>16) /* <<< NOTE! */ if(ct[n][opt[am]]>=0) am=opt[am]; } /* if ` is declared, force further optimization */ if (t[l-1]=='`') { if (opt[am]<0 || ct[n][opt[am]]<0) errout(E_ADRESS); am=opt[am]; } /* if ! is declared, force to 16-bit quantity */ if (t[l-1]=='!' && am>16 && opt[am]>=0 && bl) { am=opt[am]; } /* couldn't match anything for this opcode */ if(!bl) er=E_SYNTAX; else { /* ok, get length of instruction */ bl=le[am]; /* and add one for 65816 special instruction modes */ if( ((ct[n][am]&0x400) && memode) || ((ct[n][am]&0x800) && xmode)) { bl++; } } if (er == E_NODEF) er = E_OK; /* .byt, .asc, .word, .dsb, .fopt pseudo-op dispatch */ } else if(n==Kmvn || n==Kmvp) { bl=3; if (!w65816) er = E_65816; } else if(n==Kbyt || n==Kasc || n==Kaasc) { #ifdef DEBUG_AM fprintf(stderr, "byt pass 1 %i\n", nk+1-na1+na2); #endif bl=nk+1-na1+na2; } else if(n==Kword) { bl=2*nk+2; } else if(n==Kdsb) { er=a_term(t+1,&bl,&l,pc[segment],&afl,&label,0); } else if(n==Kfopt) { set_fopt(l-1,t+1, nk+1-na1+na2); *ll = 0; } else if(n==T_OP) { er=E_OKDEF; } else er=E_NODEF; if(!er) er=E_OKDEF; #ifdef DEBUG_AM fprintf(stderr, "guessing instruction length is %d\n", bl); #endif } if(er==E_NOLINE) { er=E_OK; *ll=0; } *al += bl; pc[segment]+=bl; if(segment==SEG_TEXT) pc[SEG_ABS]+=bl; if(segment==SEG_ABS) pc[SEG_TEXT]+=bl; return(er); } /*t_pass 2*/ int t_p2(signed char *t, int *ll, int fl, int *al) { static int afl,nafl, i,j,k,er,v,n,l,bl,sy,am,c,vv[3],v2,label; static int rlt[3]; /* relocation table */ static int lab[3]; /* undef. label table */ #if(0) (void)fl; /* quench warning */ #endif /* fl was not used in 2.2.0 so I'm overloading it for zp-optimization control */ er=E_OK; bl=0; if(*ll<0) /* <0 bei E_OK, >0 bei E_OKDEF */ { *ll=-*ll; bl=*ll; er=E_OK; } else { n=t[0]; if(n==T_OP) { n=cval(t+1); er=a_term(t+4,&v,&l,pc[segment],&nafl,&label,0); if(!er) { if(t[3]=='=') { v2=v; } else { if( (!(er=l_get(n,&v2, &afl))) && ((afl & A_FMASK)!=(SEG_UNDEF<<8)) ) { if(t[3]=='+') { if(afl && nafl) { errout(E_WPOINTER); nafl=0; } nafl = afl; v2+=v; } else if(t[3]=='-') { if( (((nafl & A_FMASK)>>8) != afl) || ((nafl & A_MASK)==A_HIGH) ) { errout(E_WPOINTER); nafl=0; } else { nafl = afl; } v2-=v; } else if(t[3]=='*') { if(afl || nafl) { errout(E_WPOINTER); nafl=0; } v2*=v; } else if(t[3]=='/') { if(afl || nafl) { errout(E_WPOINTER); nafl=0; } if(v) v2/=v; else er=E_DIV; } else if(t[3]=='|') { if(afl || nafl) { errout(E_WPOINTER); nafl=0; } v2=v|v2; } else if(t[3]=='&') { if(afl || nafl) { errout(E_WPOINTER); nafl=0; } v2=v2&v; } } } l_set(n,v2,nafl>>8); *ll=0; if(!er) er=E_NOLINE; } } else if(n==Kword) { i=1; j=0; while(!er && t[i]!=T_END) { if(!(er=a_term(t+i,&v,&l,pc[segment],&afl,&label,1))) { /*if(afl) printf("relocation 1 %04x at pc=$%04x, value now =$%04x\n", afl,pc[segment],v); */ if(afl) u_set(pc[segment]+j, afl, label, 2); t[j++]=v&255; t[j++]=(v>>8)&255; i+=l; if(t[i]!=T_END && t[i]!=',') er=E_SYNTAX; else if(t[i]==',') i++; } } *ll=j; bl=j; } else if (n == Kbin) { int j; int l; /* figure out our parameters again. repeat most of the error checking since we might not be over the total number of bogosities */ char binfnam[255]; int offset; int length; int fstart; int flen; i = 1; j = 0; flen = 0; /* get offset */ if(!(er=a_term(t+i,&offset,&l,pc[segment],&afl,&label,1))) { i += l; } if (offset < 0) er = E_ILLQUANT; if(t[i] == ',') { /* skip comma */ i++; } else { er = E_SYNTAX; } /* get length */ if (!er && !(er=a_term(t+i,&length,&l,pc[segment],&afl,&label,1))) { i += l; } if (length < 0) er = E_ILLQUANT; if(t[i] == ',') { /* skip comma */ i++; } else { er = E_SYNTAX; } /* get filename. the tokenizer can either see it as a multichar string ... */ if (!er) { int k; fstart = i; if(t[i]=='\"') { i++; k=t[i]+i+1; i++; while(i 255) er = E_NOMEM; /* buffer overflow */ } binfnam[j] = '\0'; flen = j; /* or as a 'char' if it's a single character ("word" would have been caught by the above) */ } else if(!(er=a_term(t+i,&v,&l,pc[segment],&afl,&label,1))) { binfnam[0] = v; binfnam[1] = '\0'; i += l; flen = 1; } } /* three arguments only please */ if (!er && t[i] != T_END) { er = E_SYNTAX; } if (!er) { FILE *foo; #ifdef DEBUG_AM fprintf(stderr, "binclude2 offset = %i len = %i filename = %s endchar = %i\n", offset, length, binfnam, i); #endif if (!(foo = fopen(binfnam, "r"))) { er = E_FNF; } else { fseek(foo, 0, SEEK_END); if ((length+offset) > ftell(foo)) { er = E_OUTOFDATA; } else { length = (length) ? length : (ftell(foo)-offset); } fclose(foo); } if (!er) { if (length > 65535 && !w65816) { errout(W_OVER64K); } else if (length > 16777215) { errout(W_OVER16M); } /* pass parameters back to xa.c */ *ll=length; /* bl=length+2; */ bl=length; t[0] = offset & 255; t[1] = (offset >> 8) & 255; t[2] = (offset >> 16) & 255; /* God help us if the index is > 65535 */ t[3] = fstart & 255; t[4] = (fstart >> 8) & 255; t[5] = flen; /* to massage 'char' types */ er = E_BIN; } } } else if (n==Kmvn || n==Kmvp) { /* special case these instructions' syntax */ int wide=0; i=1; j=1; /* write opcode */ t[0] = ((n == Kmvp) ? 0x44 : 0x54); while(!er && t[i]!=T_END) { if (wide) /* oops */ er = E_SYNTAX; #ifdef DEBUG_AM fprintf(stderr, "mvn mvp: %i %i %i %i %i\n", t[0], t[i], wide, i, j); #endif if(!(er=a_term(t+i,&v,&l,pc[segment],&afl,&label,1))) { /*if(afl) printf("relocation 1 %04x at pc=$%04x, value now =$%04x\n", afl,pc[segment],v); */ if(afl) u_set(pc[segment]+j, afl, label, 2); i+=l; /* for backwards compatibility, accept the old mv? $xxxx syntax, but issue a warning. mv? $00xx can be legal, so accept that too. */ if ((v & 0xff00) || (j==1 && t[i]==T_END)) { errout(W_OLDMVNS); wide = 1; t[j++] = ((v & 0xff00) >> 8); t[j++] = (v & 0x00ff); } else { t[j++] = v; } } if (j > 3) er=E_SYNTAX; if(t[i]!=T_END && t[i]!=',') er=E_SYNTAX; else if(t[i]==',') i++; } if (j != 3) er = E_SYNTAX; /* oops */ /* before we leave, swap the bytes. although disassembled as mv? src,dest it's actually represented as mv? $ddss -- see http://6502org.wikidot.com/software-65816-memorymove */ i = t[2]; t[2] = t[1]; t[1] = i; *ll = j; bl = j; if (!w65816) er = E_65816; } else if(n==Kasc || n==Kbyt || n==Kaasc) { i=1; j=0; while(!er && t[i]!=T_END) { if(t[i]=='\"') { i++; k=t[i]+i+1; i++; while(i>8) er=E_OVERFLOW; t[0]=v&255; if(!er) { *ll=j; bl=j; #ifdef DEBUG_AM fprintf(stderr, "Kdsb E_DSB %i\n", j); #endif er=E_DSB; } } if(!er) bl=j; } dsb_len = 0; } else if(n<=Lastbef) { /* instruction */ if((c=t[1])=='#') { i=2; sy=1; if(!(er=a_term(t+i,vv,&l,pc[segment],&afl,&label,1))) { /* if(1) printf("a_term returns afl=%04x\n",afl); */ rlt[0] = afl; lab[0] = label; i+=l; if(t[i]!=T_END) { if(t[i]!=',') er=E_SYNTAX; else { i++; sy++; if(!(er=a_term(t+i,vv+1,&l,pc[segment],&afl,&label,1))) { rlt[1] = afl; lab[1] = label; i+=l; if(t[i]!=T_END) { if(t[i]!=',') er=E_SYNTAX; else { i++; sy++; if(!(er=a_term(t+i,vv+2,&l,pc[segment],&afl,&label,1))) { rlt[2] = afl; lab[2] = label; i+=l; if(t[i]!=T_END) er=E_SYNTAX; } } } } } } } } else if(c==T_END) { sy=0; } else if(c=='(') { sy=7; if(!(er=a_term(t+2,vv,&l,pc[segment],&afl,&label,1))) { rlt[0] = afl; lab[0] = label; if(t[2+l]!=T_END) { if(t[2+l]==',') { if (tolower(t[3+l])=='x') sy=8; else sy=13; } else if(t[2+l]==')') { if(t[3+l]==',') { if(tolower(t[4+l])=='y') sy=9; else er=E_SYNTAX; } else if(t[3+l]!=T_END) er=E_SYNTAX; } } else er=E_SYNTAX; } } else if(c=='[') { sy=10; if(!(er=a_term(t+2,vv,&l,pc[segment],&afl,&label,1))) { rlt[0] = afl; lab[0] = label; if(t[2+l]!=T_END) { if(t[2+l]==']') { if(t[3+l]==',') { if(tolower(t[4+l])=='y') sy=11; else er=E_SYNTAX; } else if(t[3+l]!=T_END) er=E_SYNTAX; } } else er=E_SYNTAX; } } else { sy=4; if(!(er=a_term(t+1,vv,&l,pc[segment],&afl,&label,1))) { rlt[0] = afl; lab[0] = label; if(t[1+l]!=T_END) { if(t[1+l]==',') { if(tolower(t[2+l])=='y') sy=6; else if(tolower(t[2+l])=='s') sy=12; else sy=5; } else er=E_SYNTAX; } } } bl=Maxbyt+1; while(--bl) { if((am=at[sy][bl-1])>=0) { if(am>Admodes) { er=E_SYNTAX; break; } if(ct[n][am]>=0) break; for(v=0;v=0) break; if(v16 && !er && !(vv[0]&0xff0000) && opt[am]>=0) if(ct[n][opt[am]]>=0) am=opt[am]; #ifdef DEBUG_AM fprintf(stderr, "aftaa1: pc= %d, am = %d and vv[0] = %d, optimize = %d, bitmask = %d\n", pc[segment], am, vv[0], fl, (vv[0]&0xffff00)); #endif if(t[*ll-1]!='!') { if(bl && !er && !(vv[0]&0xffff00) && opt[am]>=0) { if(ct[n][opt[am]]>=0) { if (!fl || t[*ll-1]=='`') { am=opt[am]; } else { errout(W_FORLAB); } } } } #ifdef DEBUG_AM fprintf(stderr, "aftaa2: pc=%d, am=%d and vv[0]=%d, optimize=%d, bitmask=%d, op=%d\n", pc[segment], am, vv[0], fl, (vv[0]&0xffff00), ct[n][opt[am]]); #endif } if(!bl) er=E_SYNTAX; else { bl=le[am]; if( ((ct[n][am]&0x400) && memode) || ((ct[n][am]&0x800) && xmode)) { bl++; } *ll=bl; } #ifdef DEBUG_AM fprintf(stderr, "byte length is now %d\n", bl); #endif if(!er) { t[0]=ct[n][am]&0x00ff; if(ct[n][am]&0x0300) { if(ct[n][am]&0x100) { ncmos++; if(!cmosfl) er=E_CMOS; } else { n65816++; if(!w65816) er=E_65816; } } if(am!=0) { if((am<8 && !( ((ct[n][am]&0x400) && memode) || ((ct[n][am]&0x800) && xmode) )) || (am>=19 && am!=23)) { if(vv[0]&0xff00) { #ifdef DEBUG_AM fprintf(stderr, "address mode: %i address: %i\n", am, vv[0]); #endif er=E_OVERFLOW; } else t[1]=vv[0]; /*if(rlt[0]) printf("relocation 1 byte %04x at pc=$%04x, value now =$%04x\n",rlt[0],pc[segment]+1,*vv); */ if(rlt[0]) u_set(pc[segment]+1, rlt[0], lab[0], 1); } else if(((am<14 || am==23) && am!=11) || am==7) { if (vv[0]>0xffff) { #ifdef DEBUG_AM fprintf(stderr, "address mode: %i address: %i\n", am, vv[0]); #endif er=E_OVERFLOW; } else { t[1]=vv[0]&255; t[2]=(vv[0]>>8)&255; /*if(rlt[0]) printf("relocation 2 byte %04x at pc=$%04x, value now =$%04x\n",rlt[0],pc[segment]+1,*vv); */ if(rlt[0]) u_set(pc[segment]+1, rlt[0], lab[0], 2); } } else if(am==11 || am==16) { if((segment!=SEG_ABS) && (!rlt[0])) { er=E_ILLPOINTER; } else { /*printf("am=11, pc=%04x, vv[0]=%04x, segment=%d\n",pc[segment],vv[0], segment);*/ v=vv[0]-pc[segment]-le[am]; if(((v&0xff80)!=0xff80) && (v&0xff80) && (am==11)) er=E_RANGE; else { t[1]=v&255; t[2]=(v>>8)&255; } } } else if(am==14) { if(vv[0]&0xfff8 || vv[1]&0xff00) er=E_RANGE; else if((segment!=SEG_ABS) && (rlt[0] || !rlt[2])) { er=E_ILLPOINTER; } else { /*if(rlt[1]) printf("relocation 1 byte %04x at pc=$%04x, value now =$%04x\n",rlt[1],pc[segment]+1,*vv); */ if(rlt[1]) u_set(pc[segment]+1, rlt[1], lab[1], 1); t[0]=t[0]|(vv[0]<<4); t[1]=vv[1]; v=vv[2]-pc[segment]-3; if((v&0xff80) && ((v&0xff80)!=0xff80)) er=E_OVERFLOW; else t[2]=v; } } else if(am==15) { /*if(rlt[1]) printf("relocation 1 byte %04x at pc=$%04x, value now =$%04x\n",rlt[1],pc[segment]+1,*vv); */ if(rlt[1]) u_set(pc[segment]+1, rlt[1], lab[1], 1); if(vv[0]&0xfff8 || vv[1]&0xff00) er=E_OVERFLOW; else { t[0]=t[0]|(vv[0]<<4); t[1]=vv[1]; } } else if(am==17 || am==18) { t[1]=vv[0]&255; t[2]=(vv[0]>>8)&255; t[3]=(vv[0]>>16)&255; if(rlt[0]) { rlt[0]|=A_LONG; u_set(pc[segment]+1, rlt[0], lab[0], 3); } } else er=E_SYNTAX; } } } else er=E_SYNTAX; } #ifdef DEBUG_AM fprintf(stderr, "-- endof P2\n"); #endif pc[segment]+=bl; if(segment==SEG_TEXT) pc[SEG_ABS]+=bl; if(segment==SEG_ABS) pc[SEG_TEXT]+=bl; *al = bl; return(er); } int b_term(char *s, int *v, int *l, int pc) { static signed char t[MAXLINE]; int er,i,afl, label; if(!(er=t_conv((signed char*)s,t,l,pc,&i,&i,&i,1,NULL))) { er=a_term(t,v,&i,pc,&afl,&label,0); } return(er); } /* translate a string into a first-pass sequence of tokens */ static int t_conv(signed char *s, signed char *t, int *l, int pc, int *nk, int *na1, int *na2, int af, int *bytep) /* Pass1 von s nach t */ /* tr. pass1, from s to t */ { static int v,f; static int operand,o; int fl,afl; int p,q,ud,n,ll,mk,er; int m, uz, byte; static unsigned char cast; /* ich verstehe deutsch, aber verstehen andere leute nicht; so, werde ich diese bemerkungen uebersetzen ... cameron */ /* I understand German, but other folks don't, so I'll translate these comments ... Cameron */ /* note that I don't write so good tho' ;) */ *nk=0; /* comma count */ *na1=0; /* asc text count */ *na2=0; /* total bytecount in asc texts */ ll=0; er=E_OK; /* error state */ p=0; q=0; ud = uz = byte =0; mk=0; /* 0 = add'l commas ok */ fl=0; /* 1 = pass text thru */ afl=0; /* pointer flag for label */ while(s[p]==' ') p++; n=T_END; cast='\0'; if(!af) { while(s[p]!='\0' && s[p]!=';') { /* is keyword? */ if(!(er=t_keyword(s+p,&ll,&n))) break; /* valid syntax, but just not a real token? */ if(er && er!=E_NOKEY) break; /* if so, try to understand as label */ if((er=l_def((char*)s+p,&ll,&n,&f))) break; p+=ll; while(s[p]==' ') p++; if(s[p]=='=') { t[q++]=T_OP; t[q++]=n&255; t[q++]=(n>>8)&255; t[q++]='='; p++; ll=n=0; break; } else if(f && s[p]!='\0' && s[p+1]=='=') { t[q++]=T_OP; t[q++]=n&255; t[q++]=(n>>8)&255; t[q++]=s[p]; p+=2; ll=n=0; break; } else if(s[p]==':') /* to support label: ... syntax */ { p++; while(s[p]==' ') p++; l_set(n,pc,segment); /* set as address value */ n=0; } else { /* label ... syntax */ l_set(n,pc,segment); /* set as address value */ n=0; } } if(n != Kmvn && n != Kmvp && ((n & 0xff) <=Lastbef)) mk=1; /* 1= nur 1 Komma erlaubt *//* = only 1 comma ok */ } if(s[p]=='\0' || s[p]==';') { er=E_NOLINE; ll=0; } else if(!er) { p+=ll; if(ll) { t[q++]= n & 0xff; /* if( (n&0xff) == Kmacro) { t[q++]= (n >> 8) & 0xff; } */ } operand=1; while(s[p]==' ') p++; if(s[p]=='#') { mk=0; t[q++]=s[p++]; while(s[p]==' ') p++; } /* * * operand processing * byte = length of operand in bytes to be assembled * * */ /* this addresses forced high/low/two byte addressing, but only for the first operand. Further processing is done in a_term() */ /* FIXIT2 */ while(s[p]!='\0' && s[p]!=';' && !er) { if(fl) { t[q++]=s[p++]; } else { if(operand) { /* are we forcing the operand into a particular addressing mode? !, @, ` operators */ if(s[p]=='!' || s[p]=='@' || s[p]=='`') { cast=s[p]; operand= -operand+1; p++; } else if(s[p]=='(' || s[p]=='-' || s[p]=='>' || s[p]=='<' || s[p]=='[') { t[q++]=s[p++]; operand= -operand+1; /* invert to become reinverted */ } else if(s[p]=='*') { t[q++]=s[p++]; } else /* maybe it's a label */ if(isalpha(s[p]) || s[p]=='_') { m=n; er=l_search((char*)s+p,&ll,&n,&v,&afl); /* if(m==Kglobl || m==Kextzero) { if(er==E_NODEF) { er=E_OK; } t[q++]=T_LABEL; t[q++]=n & 255; t[q++]=(n>>8) & 255; } else */ if(!er) { if(afl) { t[q++]=T_POINTER; t[q++]=afl & 255; t[q++]=v & 255; t[q++]=(v>>8) & 255; } else { wval(q,v); } } else if(er==E_NODEF) { #ifdef DEBUG_AM fprintf(stderr, "could not find %s\n", (char *)s+p); #endif t[q++]=T_LABEL; t[q++]=n & 255; t[q++]=(n>>8) & 255; /* if(afl==SEG_ZEROUNDEF) uz++; */ ud++; er=E_OK; } p+=ll; } else if(s[p]<='9' && s[p]>='0') { tg_dez(s+p,&ll,&v); p+=ll; wval(q,v); } else /* handle encodings: hex, binary, octal, quoted strings */ switch(s[p]) { case '$': tg_hex(s+p+1,&ll,&v); p+=1+ll; wval(q,v); break; case '%': tg_bin(s+p+1,&ll,&v); p+=1+ll; wval(q,v); break; case '&': tg_oct(s+p+1,&ll,&v); p+=1+ll; wval(q,v); break; case '\'': case '\"': er=tg_asc(s+p,t+q,&q,&p,na1,na2,n); break; case ',': if(mk) while(s[p]!='\0' && s[p]!=';') { while(s[p]==' ') p++; *nk+=(s[p]==','); t[q++]=s[p++]; } else { *nk+=1; t[q++]=s[p++]; } break; default : er=E_SYNTAX; break; } operand= -operand+1; } else /* operator */ { o=0; if(s[p]==')' || s[p]==']') { t[q++]=s[p++]; operand =-operand+1; } else if(s[p]==',') { t[q++]=s[p++]; if(mk) fl++; *nk+=1; } else switch(s[p]) { case '+': o=1; break; case '-': o=2; break; case '*': o=3; break; case '/': o=4; break; case '<': switch (s[p+1]) { case '<': o=6; break; case '>': o=12; break; case '=': o=10; break; default : o=7; break; } break; case '>': switch (s[p+1]) { case '>': o=5; break; case '<': o=12; break; case '=': o=11; break; default: o=8; break; } break; case '=': switch (s[p+1]) { case '<': o=10; break; case '>': o=11; break; default: o=9; break; } break; case '&': if (s[p+1]=='&') o=16; else o=13; break; case '|': if (s[p+1]=='|') o=17; else o=15; break; case '^': o=14; break; default: er=E_SYNTAX; break; } if(o) { t[q++]=o; p+=lp[o]; #if(0) uz++; /* disable 8-bit detection */ #endif } operand= -operand+1; } while(s[p]==' ') p++; } } } if(!er) { /* if(uz==1 && ud==1 && byte!=2) { byte=1; } if(byte == 1) { t[q++] = T_FBYTE; } else if(byte == 2) { t[q++] = T_FADDR; } */ byte = 0; t[q++]=T_END; if(ud > 0) { er=E_NODEF; byte = 1; } } /* FIXME: this is an unholy union of two "!" implementations :-( */ t[q++]='\0'; t[q++]=cast; *l=q; if(bytep) *bytep=byte; return(er); } static int t_keyword(signed char *s, int *l, int *n) { int i = 0, j = 0, hash; if(!isalpha(s[0]) && s[0]!='.' && s[0]!='*' ) return(E_NOKEY); if(isalpha(s[0])) hash=tolower(s[0])-'a'; else hash=26; if(s[0]=='*') { j=1; while(s[j] && isspace(s[j])) j++; if(s[j]=='=') { i=Kpcdef; j++; } } if(!i) { i=ktp[hash]; hash=ktp[hash+1]; while(i='0') val=val*8+(s[i++]-'0'); *l=i; *v=val; } static void tg_hex(signed char *s, int *l, int *v) { int i=0,val=0; while((s[i]>='0' && s[i]<='9') || (tolower(s[i])<='f' && tolower(s[i])>='a')) { val=val*16+(s[i]<='9' ? s[i]-'0' : tolower(s[i])-'a'+10); i++; } *l=i; *v=val; } /* * tokenize a string - handle two delimiter types, ' and " */ static int tg_asc(signed char *s, signed char *t, int *q, int *p, int *na1, int *na2,int n) { int er=E_OK,i=0,j=0; signed char delimiter = s[i++]; #ifdef DEBUG_AM fprintf(stderr, "tg_asc token = %i\n", n); #endif t[j++]='"'; /* pass2 token for string */ j++; /* skip place for length */ while(s[i]!='\0' && s[i]!=delimiter) { /* do NOT convert for Kbin or Kaasc, or for initial parse */ if (!n || n == Kbin || n == Kaasc) { t[j++]=s[i]; } else if(s[i]!='^') { /* no escape code "^" */ t[j++]=convert_char(s[i]); } else { /* escape code */ signed char payload = s[i+1]; switch(payload) { case '\0': er=E_SYNTAX; break; case '\"': if (payload == delimiter) { t[j++]=convert_char(payload); i++; } else { er=E_SYNTAX; } break; case '\'': if (payload == delimiter) { t[j++]=convert_char(payload); i++; } else { er=E_SYNTAX; } break; case '^': t[j++]=convert_char('^'); i++; break; default: t[j++]=convert_char(payload&0x1f); i++; break; } } i++; } if(j==3) /* optimize single byte string to value */ { t[0]=T_VALUE; t[1]=t[2]; t[2]=0; t[3]=0; j++; } else { /* handle as string */ t[1]=j-2; *na1 +=1; *na2 +=j-2; } if(s[i]==delimiter) { /* in case of no error */ i++; /* skip ending delimiter */ } *q +=j; *p +=i; return(er); } xa-2.3.8/src/xat.h0000600000031500000010000000210107615405422013171 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __XA65_XAT_H__ #define __XA65_XAT_H__ extern int dsb_len; int t_p1(signed char *s, signed char *t, int *ll, int *al); int t_p2(signed char *t, int *ll, int fl, int *al); int b_term(char *s, int *v, int *l, int pc); #endif /* __XA65_XAT_H__ */ xa-2.3.8/src/xau.c0000600000031500000010000000362410405053372013172 0ustar spectrestaff/* xa65 - 65xx/65816 cross-assembler and utility suite * * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * Undefined label tracking module (also see xal.c) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include "xad.h" #include "xau.h" #include "xah.h" #include "xal.h" /* static int *ulist = NULL; static int un = 0; static int um = 0; */ int u_label(int labnr) { int i; /*printf("u_label: %d\n",labnr);*/ if(!afile->ud.ulist) { afile->ud.ulist = malloc(200*sizeof(int)); if(afile->ud.ulist) afile->ud.um=200; } for(i=0;iud.un;i++) { if(afile->ud.ulist[i] == labnr) return i; } if(afile->ud.un>=afile->ud.um) { afile->ud.um *= 1.5; afile->ud.ulist = realloc(afile->ud.ulist, afile->ud.um * sizeof(int)); if(!afile->ud.ulist) { fprintf(stderr, "Panic: No memory!\n"); exit(1); } } afile->ud.ulist[afile->ud.un] = labnr; return afile->ud.un++; } void u_write(FILE *fp) { int i, d; char *s; /*printf("u_write: un=%d\n",afile->ud.un);*/ fputw(afile->ud.un, fp); for(i=0;iud.un;i++) { l_vget(afile->ud.ulist[i], &d, &s); fprintf(fp,"%s", s); fputc(0,fp); } free(afile->ud.ulist); afile->ud.ulist=NULL; afile->ud.um = afile->ud.un = 0; } xa-2.3.8/src/xau.h0000600000031500000010000000160506263223121013172 0ustar spectrestaff /* xa65 - 6502 cross assembler and utility suite Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ extern int u_label(int labnr); extern void u_write(FILE *fp); xa-2.3.8/tests/0000755000031500000010000000000013125353754012620 5ustar spectrestaffxa-2.3.8/tests/README0000644000031500000010000000346513125354574013511 0ustar spectrestaffThis is a directory of test suites for complex or pathological cases that have been repaired (?) in the current version. It is primarily for internal testing, but is here for your interest. Starting with 2.3.6, you should not normally need to run these directly unless 'make test' fails. If you do, use harness: ./harness -cc=... -cflags=... -make=... -tests=testdir,testdir,testdir,... If -tests is omitted, all tests are run. Don't run the makefiles directly, if they exist; they may not work properly. If a Makefile is not present, then the test harness assembles "test.s" and compares it with "ok". adrm/ Addressing mode test (especially the optimizer and quantity prefixes) nonl/ Patryk's no-new-line-on-last-line cases ;) fordef/ Optimizer warnings for forward defined labels relocundef/ Tests for the detection of undefined references during a reloc65 export ldoreloc/ Test case for the relocation table reading of ldo when undef'd refs are involved comcom/ Comments-with-comments-with-commands-etc. for testing -M recmac/ Recursive macro evaluation testing openpp/ Testing of open #if*s in pp cpp/ Random preprocessor tests, mostly crap incerr/ 1) .xl/.al should error without -w 2) error should be in the correct file ('816) binclude/ Binary include code with some weird casing chppch/ Changing preprocessor characters (-p) charset/ Tests of when charsets should be honoured and when not mvnmvp/ Test MVN MVP unusual addressing mode ('816) dos51/ Regression test, label scoping, "real world code" cpktest/ Regression test, label listing, "real world code" op816/ Regression test for '816 opcodes (thanks Alessandro Gatti) branch/ Branch range test masmcom/ Another test for -M that generates totally valid code quotch/ Test quoting problematic characters (thanks Simon Rowe) Cameron Kaiser, André Fachat xa-2.3.8/tests/adrm/0000755000031500000010000000000013125354742013541 5ustar spectrestaffxa-2.3.8/tests/adrm/02.asm0000644000031500000010000000053510552212126014455 0ustar spectrestaff .word $0400 * = $0400 q = $0005 fizz /* these should be optimized to zero page */ sta $05 sta $0005 sta q dec q inc q lda <$0005 /* these should not */ stx !$0005 sta !q sta $8765 stx $919c inc !q dec $8342 sta $4431 inc $79e0 sty $1b0a jsr $ffe4 jmp $fce2 jmp breadbox lsr $2020 bne fizz rts breadbox rts beq fizz rts xa-2.3.8/tests/adrm/02.ok0000644000031500000010000000007412004321760014303 0ustar spectrestaff………Ææ¥Že‡Žœ‘îÎBƒ1DîàyŒ  äÿLâüL6N ÐË``ðÇ`xa-2.3.8/tests/adrm/816.asm0000644000031500000010000000047110552212412014547 0ustar spectrestaff .word $0400 * = $0400 q = $0005 r = $000005 fizz /* these should be optimized to zero page */ sta $05 sta $0005 sta q sta r /* 16-bit */ sta !$0005 sta !q sta $8765 /* 24-bit */ sta @q sta @$000005 sta $876543 rts jmp $fce2 jmp $99fce2 jmp breadbox jmp @breadbox breadbox rts bne fizz rts xa-2.3.8/tests/adrm/816.ok0000644000031500000010000000006212004321763014400 0ustar spectrestaff…………e‡Ce‡`Lâü\âü™L,\,`ÐÑ`xa-2.3.8/tests/adrm/Makefile0000644000031500000010000000116112004322113015156 0ustar spectrestaffdefault: # xa should not allow this to happen. if it does, this test is no good. ../../xa 816.asm || exit 0 && exit 1 ../../xa zab.asm || exit 0 && exit 1 ../../xa zpa.asm || exit 0 && exit 1 ../../xa -C c02.asm || exit 0 && exit 1 # expected-to-fail tests did fail. should be no more errors now. ../../xa -C 02.asm -o 02.o ../hextool -cmp=02.ok < 02.o ../../xa c02.asm -o c02.o ../hextool -cmp=c02.ok < c02.o ../../xa -w 816.asm -o 816.o ../hextool -cmp=816.ok < 816.o ../../xa -w zab.asm -o zab.o ../hextool -cmp=zab.ok < zab.o ../../xa -w zpa.asm -o zpa.o ../hextool -cmp=zpa.ok < zpa.o clean: rm -f *.o xa-2.3.8/tests/adrm/bip.inc0000644000031500000010000000066510552213771015012 0ustar spectrestaff/* - tbasic.0.asm: if you make vecwri absolute with !, then the branch gets generated as if it were NOT absolute. works okay without it (and gets a warning) */ test lda !$0095 bne test ldx #13 lup0 lda @vecwri,x sta $2005,x dex bne lup0 lda #$00 sta $0020 lda #$02 sta $0021 lda #$ff sta $0022 lda #$13 sta $0023 jmp $2003 vectors .byt $4c, $5a, $1e, $4c, $a0, $1e, $4c, $00, $01 vecwri = vectors - 1 xa-2.3.8/tests/adrm/c02.asm0000644000031500000010000000052710552213231014617 0ustar spectrestaff .word $0400 * = $0400 q = $0005 fizz /* these should be optimized to zero page */ sta $05 sta $0005 sta q dec q inc q /* these should not */ stx !$0005 sta !q sta $8765 stx $919c inc !q inc; a dec $8342 dec; a sta $4431 inc $79e0 sty $1b0a jsr $ffe4 jmp $fce2 jmp breadbox lsr $2020 rts breadbox rts bne fizz rts xa-2.3.8/tests/adrm/c02.ok0000644000031500000010000000007212004321766014452 0ustar spectrestaff………ÆæŽe‡Žœ‘îÎBƒ:1DîàyŒ  äÿLâüL4N ``ÐÉ`xa-2.3.8/tests/adrm/zab.asm0000644000031500000010000000005410551604666015021 0ustar spectrestaff .word $4000 * = $4000 #include "bip.inc" xa-2.3.8/tests/adrm/zab.ok0000644000031500000010000000005712004321772014642 0ustar spectrestaff@­•Ðû¢ ¿#@ ÊÐö©… ©…!©ÿ…"©…#L LZL Lxa-2.3.8/tests/adrm/zpa.asm0000644000031500000010000000005410551604615015031 0ustar spectrestaff .word $0000 * = $0000 #include "bip.inc" xa-2.3.8/tests/adrm/zpa.ok0000644000031500000010000000005712004321775014663 0ustar spectrestaff­•Ðû¢ ¿# ÊÐö©… ©…!©ÿ…"©…#L LZL Lxa-2.3.8/tests/binclude/0000755000031500000010000000000013125354742014403 5ustar spectrestaffxa-2.3.8/tests/binclude/Makefile0000644000031500000010000000045012073077312016036 0ustar spectrestaffdefault: ../../xa test.asm -o test.o ../hextool -cmp=test.ok < test.o ../../xa -w test.asm -o test816.o ../hextool -cmp=test.ok < test816.o ../../xa test2.asm -o test2.o ../hextool -cmp=test2.ok < test2.o ../../xa test3.asm -o test3.o ../hextool -cmp=test.ok < test3.o clean: rm -f *.o xa-2.3.8/tests/binclude/README.1st0000600000031500000010000001204711032605430015751 0ustar spectrestaffThis is the readme for xa, a cross-assembler for the 6502 and 65816 CPUs (and derivatives). xa is a small, fast, portable two-pass assembler that compiles under most ANSI C compilers. It is distributed under the GNU Public License (see COPYING). The current version is 2.3.3, which implements several compatibility improvements on 2.3.2, a bug fix to the 2.3.0 version. 2.3.0 itself features many compatibility improvements and new man-based documentation. It also completed the merge of the 65816 and 6502/R65C02 versions and thus the current xa can generate code for all targets now. To install on a generic Unixy thing, you should be able to just type % make # to build the executable, and if it works ... % make install # to install man pages and binaries into the system This will create xa along with its various support utilities. Try assembling the cpk depacker in examples/ as a test. xa also comes with uncpk (a program for generating cpk archives) and printcbm (a program for listing Commodore BASIC test) and file65, ldo65 and reloc65 for displaying, linking and relocating o65 files in Andre's relocatable format (see doc/fileformats.txt). The loader/ directory also has goodies for managing relocatable binaries. Don't forget the man pages in man/. Install these into your MANPATH at your leisure, or read them with nroff -man (and/or groff -man). xa is no longer broadly supported outside of Unix due to my inability to test it, but has nothing that should impair it from compiling elsewhere. To wit, DOS compilation is still supported with the GO32 package. You should just be able to type C:\> make dos In addition, there are compatibility updates to allow it to compile under Microsoft Visual Studio and mingw. It should compile under VS2005 as written; look in the vstudio directory for solution and project files provided by Fabian Nunez. For mingw, use make mingw Similarly, Amiga and Atari ST compilation should still also function with their particular compatible packages. xa has a companion disassembler, the dxa package. dxa is not included in the standard xa distribution, but can be downloaded from the xa home page at http://www.floodgap.com/retrotech/xa/ Please check by periodically for the latest version of both packages. xa was originally written and maintained by Andre Fachat. The current version is maintained by Cameron Kaiser. Please send me your comments at ckaiser@floodgap.com -- Andre's original readme follows and applies generally to the present version. ------------------------------------------------------------------------------- XA is a 6502 cross compiler: - under GNU public license - can produce _relocatable_ binaries - The full fileformat description and 6502 file loader included. - also included relocation and info utilites, as well as linker - for any ANSI-C compliant computer (only utilities need 'stat' call for file size). - fast by hashtables - Rockwell CMOS opcodes - running under DOS and any ANSI C system (Unix, Amiga, Atari ST) I developed this cross assembler for the 6502 CPU family quite some time ago on my Atari ST. The assembler has successfully been ported to Amiga and Unix computer (ported? just compiled... :-) Lately I came across the problem to need relocatable 6502 binary files, so I revised the assembler from version 2.0.7 to 2.1.0, adding a (admittedly proprietary) 6502 relocatable binary format. But there are not many other formats around and they didn't fit my needs. I have developed this format myself and it is under the GNU public license. With version 2.1.1 the 'official' version of the fileformat is supported. To compile it, just type "make" (if you have the GNU gcc. If not, edit the Makefile for the compiler options). This produces "xa", the cross assembler; "uncpk", a small packing utility (where the C64 counterpart is in the examples subdirectory), "printcbm", that lists C64 BASIC files and 'file65' that prints some information about o65 files. The "loader" in the loader subdirectory is a basic 6502 implementation of a relocating binary loader. "file65" prints file information on 'o65' relocatable files. "reloc65" can relocate 'o65' files. If you want to use it under DOS, you have to have the GO32 DOS crosscompiling tools to compile. Then just type "make dos" and you'll end up with the appropriate DOS binaries. This has been tested only under i386 Linux, however. Another archive with the DOS binaries included is provided. One problem on the Atari was it's broken "malloc". Therefore I used to alloc everything in one chunk and divide the memory by hand. So everything was kind of statically allocated. This is almost gone now. Only the temporary storage between pass1 and pass2 and the preprocessor are still allocated in one chunk (size definitions in xah.h). The rest is allocated as needed. The docs are in the 'doc' subdir. There also is a description of the 6502 relocatable binary format. If you think some things could be expressed in a better way, feel free and mail me to improve my english ;-) [ The documentation is now maintained in man(1) format in man/ . -- CK ] Andre xa-2.3.8/tests/binclude/sd/0000755000031500000010000000000012073077224015007 5ustar spectrestaffxa-2.3.8/tests/binclude/sd/README.2nd0000600000031500000010000001204712073077224016345 0ustar spectrestaffThis is the readme for xa, a cross-assembler for the 6502 and 65816 CPUs (and derivatives). xa is a small, fast, portable two-pass assembler that compiles under most ANSI C compilers. It is distributed under the GNU Public License (see COPYING). The current version is 2.3.3, which implements several compatibility improvements on 2.3.2, a bug fix to the 2.3.0 version. 2.3.0 itself features many compatibility improvements and new man-based documentation. It also completed the merge of the 65816 and 6502/R65C02 versions and thus the current xa can generate code for all targets now. To install on a generic Unixy thing, you should be able to just type % make # to build the executable, and if it works ... % make install # to install man pages and binaries into the system This will create xa along with its various support utilities. Try assembling the cpk depacker in examples/ as a test. xa also comes with uncpk (a program for generating cpk archives) and printcbm (a program for listing Commodore BASIC test) and file65, ldo65 and reloc65 for displaying, linking and relocating o65 files in Andre's relocatable format (see doc/fileformats.txt). The loader/ directory also has goodies for managing relocatable binaries. Don't forget the man pages in man/. Install these into your MANPATH at your leisure, or read them with nroff -man (and/or groff -man). xa is no longer broadly supported outside of Unix due to my inability to test it, but has nothing that should impair it from compiling elsewhere. To wit, DOS compilation is still supported with the GO32 package. You should just be able to type C:\> make dos In addition, there are compatibility updates to allow it to compile under Microsoft Visual Studio and mingw. It should compile under VS2005 as written; look in the vstudio directory for solution and project files provided by Fabian Nunez. For mingw, use make mingw Similarly, Amiga and Atari ST compilation should still also function with their particular compatible packages. xa has a companion disassembler, the dxa package. dxa is not included in the standard xa distribution, but can be downloaded from the xa home page at http://www.floodgap.com/retrotech/xa/ Please check by periodically for the latest version of both packages. xa was originally written and maintained by Andre Fachat. The current version is maintained by Cameron Kaiser. Please send me your comments at ckaiser@floodgap.com -- Andre's original readme follows and applies generally to the present version. ------------------------------------------------------------------------------- XA is a 6502 cross compiler: - under GNU public license - can produce _relocatable_ binaries - The full fileformat description and 6502 file loader included. - also included relocation and info utilites, as well as linker - for any ANSI-C compliant computer (only utilities need 'stat' call for file size). - fast by hashtables - Rockwell CMOS opcodes - running under DOS and any ANSI C system (Unix, Amiga, Atari ST) I developed this cross assembler for the 6502 CPU family quite some time ago on my Atari ST. The assembler has successfully been ported to Amiga and Unix computer (ported? just compiled... :-) Lately I came across the problem to need relocatable 6502 binary files, so I revised the assembler from version 2.0.7 to 2.1.0, adding a (admittedly proprietary) 6502 relocatable binary format. But there are not many other formats around and they didn't fit my needs. I have developed this format myself and it is under the GNU public license. With version 2.1.1 the 'official' version of the fileformat is supported. To compile it, just type "make" (if you have the GNU gcc. If not, edit the Makefile for the compiler options). This produces "xa", the cross assembler; "uncpk", a small packing utility (where the C64 counterpart is in the examples subdirectory), "printcbm", that lists C64 BASIC files and 'file65' that prints some information about o65 files. The "loader" in the loader subdirectory is a basic 6502 implementation of a relocating binary loader. "file65" prints file information on 'o65' relocatable files. "reloc65" can relocate 'o65' files. If you want to use it under DOS, you have to have the GO32 DOS crosscompiling tools to compile. Then just type "make dos" and you'll end up with the appropriate DOS binaries. This has been tested only under i386 Linux, however. Another archive with the DOS binaries included is provided. One problem on the Atari was it's broken "malloc". Therefore I used to alloc everything in one chunk and divide the memory by hand. So everything was kind of statically allocated. This is almost gone now. Only the temporary storage between pass1 and pass2 and the preprocessor are still allocated in one chunk (size definitions in xah.h). The rest is allocated as needed. The docs are in the 'doc' subdir. There also is a description of the 6502 relocatable binary format. If you think some things could be expressed in a better way, feel free and mail me to improve my english ;-) [ The documentation is now maintained in man(1) format in man/ . -- CK ] Andre xa-2.3.8/tests/binclude/test.asm0000644000031500000010000000040511041467454016063 0ustar spectrestaff .word $9000 * = $9000 w = 10 glorb .dsb 9,10 ; +9 .byt 6, 6, 6, "devil", 'Q' ; +9 => 18 .bin 0,5,'README.1st' ; +5 => 23 .bin w,w+256,'README.1st' ; +266 => 289 ($0121) gleeb ; $0123 jmp glorb ; should be $9121 (remember the SA) jmp gleeb bne * xa-2.3.8/tests/binclude/test.ok0000644000031500000010000000045312004322240015676 0ustar spectrestaff devilQThis e readme for xa, a cross-assembler for the 6502 and 65816 CPUs (and derivatives). xa is a small, fast, portable two-pass assembler that compiles under most ANSI C compilers. It is distributed under the GNU Public License (see COPYING). The current version is 2.3.3,LL!‘Ðþxa-2.3.8/tests/binclude/test2.asm0000644000031500000010000000024611041466236016145 0ustar spectrestaff .word $9000 * = $9000 w = 10 glorb .dsb 9,10 .byt 6, 6, 6, "devil", 'Q' .bin 0,109,'README.1st' .bin w,w+119,'README.1st' gleeb jmp glorb jmp gleeb bne * xa-2.3.8/tests/binclude/test2.ok0000644000031500000010000000041212004322245015760 0ustar spectrestaff devilQThis is the readme for xa, a cross-assembler for the 6502 and 65816 CPUs (and derivatives). xa is a small, fae readme for xa, a cross-assembler for the 6502 and 65816 CPUs (and derivatives). xa is a small, fast, portable two-pass assembleLL‘Ðþxa-2.3.8/tests/binclude/test3.asm0000644000031500000010000000046512073077256016157 0ustar spectrestaff/* This should be the same as test.ok */ .word $9000 * = $9000 w = 10 glorb .dsb 9,10 ; +9 .byt 6, 6, 6, "devil", 'Q' ; +9 => 18 .bin 0,5,'sd/README.2nd' ; +5 => 23 .bin w,w+256,'sd/README.2nd' ; +266 => 289 ($0121) gleeb ; $0123 jmp glorb ; should be $9121 (remember the SA) jmp gleeb bne * xa-2.3.8/tests/branch/0000755000031500000010000000000013125354743014054 5ustar spectrestaffxa-2.3.8/tests/branch/Makefile0000644000031500000010000000041112447652647015522 0ustar spectrestaffdefault: # xa should not allow this to happen. if it does, this test is no good. ../../xa bor.s || exit 0 && exit 1 # expected-to-fail tests did fail. should be no more errors now. ../../xa -w bir.s -o test.o ../hextool -cmp=bir.ok < test.o clean: rm -f *.o xa-2.3.8/tests/branch/bir.ok0000644000031500000010000000021412447652225015162 0ustar spectrestaffÐ|ð€°üpúPøö0ôxa-2.3.8/tests/branch/bir.s0000644000031500000010000000015112447652210015005 0ustar spectrestaff/* just in range */ bcc pdq pdq bne xyz .dsb 124,6 xyz beq pdq bcs xyz bvs xyz bvc xyz bpl xyz bmi xyz xa-2.3.8/tests/branch/bor.s0000644000031500000010000000015112447652602015020 0ustar spectrestaff/* just in range */ bcc pdq pdq bne xyz .dsb 125,6 xyz beq pdq bcs xyz bvs xyz bvc xyz bpl xyz bmi xyz xa-2.3.8/tests/chardelimiter/0000755000031500000010000000000013125354743015433 5ustar spectrestaffxa-2.3.8/tests/chardelimiter/ok0000644000031500000010000000002312004324557015755 0ustar spectrestaff©A©A1234512345"''"xa-2.3.8/tests/chardelimiter/test.s0000644000031500000010000000021512004324554016564 0ustar spectrestaff *=$033c lda #"A" lda #'A' .asc "12345" .asc '12345' .asc "^"" ; ^ is escape character .asc '^'' .asc "'" .asc '"' .asc "^n" xa-2.3.8/tests/charset/0000755000031500000010000000000013125354743014250 5ustar spectrestaffxa-2.3.8/tests/charset/Makefile0000644000031500000010000000042112004341647015677 0ustar spectrestaffdefault: ../../xa test.s ../hextool -cmp=no-charset.o < a.o65 ../../xa -O PETSCII test.s ../hextool -cmp=petscii.o < a.o65 ../../xa -O PETSCREEN test.s ../hextool -cmp=petscreen.o < a.o65 ../../xa -O HIGH test.s ../hextool -cmp=high.o < a.o65 clean: rm -rf a.o65 xa-2.3.8/tests/charset/README.1st0000600000031500000010000001203111135657773015633 0ustar spectrestaffThis is the readme for xa, a cross-assembler for the 6502 and 65816 CPUs (and derivatives). xa is a small, fast, portable two-pass assembler that compiles under most ANSI C compilers. It is distributed under the GNU Public License (see COPYING). The current version is 2.3.4, which implements multiple improvements on 2.3.2, a bug fix to the 2.3.0 version. 2.3.0 itself features many compatibility improvements and new man-based documentation. It also completed the merge of the 65816 and 6502/R65C02 versions and thus the current xa can generate code for all targets now. To install on a generic Unixy thing, you should be able to just type % make # to build the executable, and if it works ... % make install # to install man pages and binaries into the system This will create xa along with its various support utilities. Try assembling the cpk depacker in examples/ as a test. xa also comes with uncpk (a program for generating cpk archives) and printcbm (a program for listing Commodore BASIC test) and file65, ldo65 and reloc65 for displaying, linking and relocating o65 files in Andre's relocatable format (see doc/fileformats.txt). The loader/ directory also has goodies for managing relocatable binaries. Don't forget the man pages in man/. Install these into your MANPATH at your leisure, or read them with nroff -man (and/or groff -man). xa is no longer broadly supported outside of Unix due to my inability to test it, but has nothing that should impair it from compiling elsewhere. To wit, DOS compilation is still supported with the GO32 package. You should just be able to type C:\> make dos In addition, there are compatibility updates to allow it to compile under Microsoft Visual Studio and mingw. It should compile under VS2005 as written; look in the vstudio directory for solution and project files provided by Fabian Nunez. For mingw, use make mingw Similarly, Amiga and Atari ST compilation should still also function with their particular compatible packages. xa has a companion disassembler, the dxa package. dxa is not included in the standard xa distribution, but can be downloaded from the xa home page at http://www.floodgap.com/retrotech/xa/ Please check by periodically for the latest version of both packages. xa was originally written and maintained by Andre Fachat. The current version is maintained by Cameron Kaiser. Please send me your comments at ckaiser@floodgap.com -- Andre's original readme follows and applies generally to the present version. ------------------------------------------------------------------------------- XA is a 6502 cross compiler: - under GNU public license - can produce _relocatable_ binaries - The full fileformat description and 6502 file loader included. - also included relocation and info utilites, as well as linker - for any ANSI-C compliant computer (only utilities need 'stat' call for file size). - fast by hashtables - Rockwell CMOS opcodes - running under DOS and any ANSI C system (Unix, Amiga, Atari ST) I developed this cross assembler for the 6502 CPU family quite some time ago on my Atari ST. The assembler has successfully been ported to Amiga and Unix computer (ported? just compiled... :-) Lately I came across the problem to need relocatable 6502 binary files, so I revised the assembler from version 2.0.7 to 2.1.0, adding a (admittedly proprietary) 6502 relocatable binary format. But there are not many other formats around and they didn't fit my needs. I have developed this format myself and it is under the GNU public license. With version 2.1.1 the 'official' version of the fileformat is supported. To compile it, just type "make" (if you have the GNU gcc. If not, edit the Makefile for the compiler options). This produces "xa", the cross assembler; "uncpk", a small packing utility (where the C64 counterpart is in the examples subdirectory), "printcbm", that lists C64 BASIC files and 'file65' that prints some information about o65 files. The "loader" in the loader subdirectory is a basic 6502 implementation of a relocating binary loader. "file65" prints file information on 'o65' relocatable files. "reloc65" can relocate 'o65' files. If you want to use it under DOS, you have to have the GO32 DOS crosscompiling tools to compile. Then just type "make dos" and you'll end up with the appropriate DOS binaries. This has been tested only under i386 Linux, however. Another archive with the DOS binaries included is provided. One problem on the Atari was it's broken "malloc". Therefore I used to alloc everything in one chunk and divide the memory by hand. So everything was kind of statically allocated. This is almost gone now. Only the temporary storage between pass1 and pass2 and the preprocessor are still allocated in one chunk (size definitions in xah.h). The rest is allocated as needed. The docs are in the 'doc' subdir. There also is a description of the 6502 relocatable binary format. If you think some things could be expressed in a better way, feel free and mail me to improve my english ;-) [ The documentation is now maintained in man(1) format in man/ . -- CK ] Andre xa-2.3.8/tests/charset/high.o0000644000031500000010000000012712004341517015335 0ustar spectrestaffThis is the readme fThis is thtest2ÆïïÂáòFooBarÆïïÂáòAa FooBarThis is thBarfooAa ©Á©Áxa-2.3.8/tests/charset/no-charset.o0000644000031500000010000000012712004341273016460 0ustar spectrestaffThis is the readme fThis is thtest2FooBarFooBarFooBarAa FooBarThis is thBarfooAa ©A©Axa-2.3.8/tests/charset/petscii.o0000644000031500000010000000012711143477402016064 0ustar spectrestaffThis is the readme fThis is thtest2fOObARFooBarfOObARAa FooBarThis is thBarfooAa ©a©axa-2.3.8/tests/charset/petscreen.o0000644000031500000010000000012712004341504016402 0ustar spectrestaffThis is the readme fThis is thtest2FBFooBarFBAa FooBarThis is thBarfooAa ©A©Axa-2.3.8/tests/charset/test.s0000644000031500000010000000035111143477373015415 0ustar spectrestaff .word $9000 * = $9000 w = 10 .bin 0,10+w,"README.1st" .bin 0,10,"README.1st" #include "test2.s" .byt "FooBar" .aasc "FooBar" .asc "FooBar",65,97,10 .aasc "FooBar" .bin 0,10,"README.1st" .aasc "Barfoo",65,97,10 lda #'A' lda #"A" xa-2.3.8/tests/charset/test2.s0000644000031500000010000000001611143477360015471 0ustar spectrestaff.aasc "test2" xa-2.3.8/tests/chppch/0000755000031500000010000000000013125354743014064 5ustar spectrestaffxa-2.3.8/tests/chppch/Makefile0000644000031500000010000000015512004342675015521 0ustar spectrestaffdefault: ../../xa -p'~' -e test.out test.c ../hextool -cmp=ok.out < test.out clean: rm -f a.o65 test.out xa-2.3.8/tests/chppch/ok.out0000644000031500000010000000005112447451012015213 0ustar spectrestaff12+12=12+12=24 10+10=10+10=20 5+5=5+5=10 xa-2.3.8/tests/chppch/qwerty.h0000644000031500000010000000004011032611204015541 0ustar spectrestaff rts #print 12+12 ~print 10+10 xa-2.3.8/tests/chppch/test.c0000644000031500000010000000004012004342417015167 0ustar spectrestaff#include "qwerty.h" ~print 5+5 xa-2.3.8/tests/comcom/0000755000031500000010000000000013125354743014074 5ustar spectrestaffxa-2.3.8/tests/comcom/Makefile0000644000031500000010000000047612004343515015531 0ustar spectrestaffdefault: # this should fail. ../../xa scomcom.asm || exit 0 && exit 1 # it did fail. these should now all succeed. ../../xa -M scomcom.asm ../hextool -cmp=scomcomm.ok < a.o65 ../../xa comcom.asm ../hextool -cmp=comcom.ok < a.o65 ../../xa -M comcom.asm ../hextool -cmp=comcomm.ok < a.o65 clean: rm -f a.o65 xa-2.3.8/tests/comcom/comcom.asm0000644000031500000010000000047410551345034016051 0ustar spectrestaff .word $c000 * = $c000 lda #147 ; depending on the -M option:lda #65 jsr $ffd2:rts ; maybe some stuff out here:tay ; there will be:cli ; extra code:sei ; or not:rti ; let's ; be ; tricky : ; does it ; work? :nop:nop: ; let's see! ; rts /* hey, ; what about now? : brk */ // do I make you sexy? ; :brk rti xa-2.3.8/tests/comcom/comcom.ok0000644000031500000010000000002112004343074015663 0ustar spectrestaffÀ©“©A Òÿ`¨Xx@êê@xa-2.3.8/tests/comcom/comcomm.ok0000644000031500000010000000001112004343051016032 0ustar spectrestaffÀ©“ Òÿ`@xa-2.3.8/tests/comcom/scomcom.asm0000644000031500000010000000006010551342713016224 0ustar spectrestaff; some comment: *2 = 1 start lda #1: sta 2 xa-2.3.8/tests/comcom/scomcomm.ok0000644000031500000010000000000412004343304016220 0ustar spectrestaff©…xa-2.3.8/tests/cpktest/0000755000031500000010000000000013125354743014274 5ustar spectrestaffxa-2.3.8/tests/cpktest/Makefile0000644000031500000010000000037212447655520015741 0ustar spectrestaffdefault: ../../xa -l test.l -o test.o pack_eng.a65 cmp test.l english.l || exit 1 ../hextool -cmp=eng.ok < test.o ../../xa -l test.l -o test.o pack_ger.a65 cmp test.l deutsch.l || exit 1 ../hextool -cmp=de.ok < test.o clean: rm -f *.o test.l xa-2.3.8/tests/cpktest/c64def.def0000600000031500000010000001724512447654537016042 0ustar spectrestaff /* VIC 6567 */ #define VIC_S0_X 0 #define VIC_S0_Y 1 #define VIC_S1_X 2 #define VIC_S1_Y 3 #define VIC_S2_X 4 #define VIC_S2_Y 5 #define VIC_S3_X 6 #define VIC_S3_Y 7 #define VIC_S4_X 8 #define VIC_S4_Y 9 #define VIC_S5_X 10 #define VIC_S5_Y 11 #define VIC_S6_X 12 #define VIC_S6_Y 13 #define VIC_S7_X 14 #define VIC_S7_Y 15 #define VIC_SP_MSB 16 #define VIC_SR1 17 #define VIC_IRQ_RASTER 18 #define VIC_LP_X 19 #define VIC_LP_Y 20 #define VIC_SP_EN 21 #define VIC_SR2 22 #define VIC_SP_EXPY 23 #define VIC_BASEADR 24 #define VIC_IRR 25 #define VIC_IMR 26 #define VIC_SP_PRIOR 27 #define VIC_SP_MCOLOR 28 #define VIC_SP_EXPX 29 #define VIC_SP_SCOLL 30 #define VIC_SP_BCOLL 31 #define VIC_EXTCOL 32 #define VIC_BCKCOL0 33 #define VIC_BCKCOL1 34 #define VIC_BCKCOL2 35 #define VIC_BCKCOL3 36 #define VIC_SP_MCOL0 37 #define VIC_SP_MCOL1 38 #define VIC_S0_COL 39 #define VIC_S1_COL 40 #define VIC_S2_COL 41 #define VIC_S3_COL 42 #define VIC_S4_COL 43 #define VIC_S5_COL 44 #define VIC_S6_COL 45 #define VIC_S7_COL 46 #define COL_SCHWARZ 0 #define COL_WEISS 1 #define COL_ROT 2 #define COL_TUERKIS 3 #define COL_VIOLETT 4 #define COL_GRUEN 5 #define COL_BLAU 6 #define COL_GELB 7 #define COL_ORANGE 8 #define COL_BRAUN 9 #define COL_HELLROT 10 #define COL_GRAU1 11 #define COL_GRAU2 12 #define COL_HELLGRUEN 13 #define COL_HELLBLAU 14 #define COL_GRAU3 15 #define VIC $d000 /* SID 6581 */ #define SID_0FREQL 0 #define SID_0FREQH 1 #define SID_0PULSL 2 #define SID_0PULSH 3 #define SID_0SR 4 #define SID_0ATTDEC 5 #define SID_0SUSREL 6 #define SID_1FREQL 7 #define SID_1FREQH 8 #define SID_1PULSL 9 #define SID_1PULSH 10 #define SID_1SR 11 #define SID_1ATTDEC 12 #define SID_1SUSREL 13 #define SID_2FREQL 14 #define SID_2FREQH 15 #define SID_2PULSL 16 #define SID_2PULSH 17 #define SID_2SR 18 #define SID_2ATTDEC 19 #define SID_2SUSREL 20 #define SID_FILTL 21 #define SID_FILTH 22 #define SID_SR1 23 #define SID_SR2 24 #define SID $d800 /* CIA 6526 */ #define CIA_DRA 0 #define CIA_DRB 1 #define CIA_DDRA 2 #define CIA_DDRB 3 #define CIA_TAL 4 #define CIA_TAH 5 #define CIA_TBL 6 #define CIA_TBH 7 #define CIA_TOD_THS 8 #define CIA_TOD_SEC 9 #define CIA_TOD_MIN 10 #define CIA_TOD_HR 11 #define CIA_SDR 12 #define CIA_ICR 13 #define CIA_CRA 14 #define CIA_CRB 15 #define CIA1 $dc00 #define CIA2 $dd00 /* ACIA 6551 */ #define ACIA_DR 0 #define ACIA_SR 1 #define ACIA_CMD 2 #define ACIA_CTRL 3 #define ACIA $d600 /* Basic */ #define INT $14 #define PRGANF $2b #define VARANF $2d #define ARRANF $2f #define ARREND $31 #define STRANF $33 #define STRPTR $35 #define RAMEND $37 #define VARNAME $45 #define VARADR $47 #define AKKU3 $57 #define AKKU4 $5c #define FAC $61 #define ARG $69 #define CHRGET $73 #define CHRGOT $79 #define PRGPTR $7a #define V_ERR $0300 #define V_WARM $0302 #define V_CONV2CODE $0304 #define V_CONV2ASC $0306 #define V_GETBEFADR $0308 #define V_GETAUSDR $030a #define SYS_AKKU $030c #define SYS_XR $030d #define SYS_YR $030e #define SYS_SR $030f #define READY $a474 #define LINEIN $a560 #define INTOUT $bdcd /* Betriebssystem */ #define STATUS $90 #define FNAMLEN $b7 #define LOGFNR $b8 #define SECADR $b9 #define DEVADR $ba #define FNAMPTR $bb #define IOANF $c1 #define IOEND $c3 #define LASTKEY $c5 #define NUMKEY $c6 #define REVFL $c7 #define INLINEEND $c8 #define INZEILE $c9 #define INSPALTE $ca #define PRESSEDKEY $cb #define CRSRFLASH $cc #define CRSRFLASHCNT $cd #define CHARUNDERCRSR $ce #define CRSRFLASHFL $cf #define KEYINPUTFL $d0 #define LINEADR $d1 #define CRSRSPALTE $d3 #define HKFL $d4 #define LENGTHOFLINE $d5 #define CRSRZEILE $d6 #define DIV $d7 #define NUMOFINS $d8 #define RS232INBUFPTR $f7 #define RS232OUTBUFPTR $f9 #define P1 $fb /* freier Pointer */ #define P2 $fd /* freier Pointer */ #define INBUF $200 #define V_USR $0311 #define V_IRQ $0314 #define V_BRK $0316 #define V_NMI $0318 #define V_OPEN $031a #define V_CLOSE $031c #define V_CHKIN $031e #define V_CKOUT $0320 #define V_CLRCH $0322 #define V_INPUT $0324 #define V_OUTPUT $0326 #define V_STOP $0328 #define V_GET $032a #define V_CLALL $032c #define V_WARMSTART $032e #define V_LOAD $0330 #define V_SAVE $0332 #define SENDNAM $f3d5 #define CLSFIL $f642 #define INICIA $ff84 #define INIRAM $ff87 #define INIIO $ff8a #define INIIOVEC $ff8d #define SETST $ff90 #define SECLISTEN $ff93 #define SECTALK $ff96 #define RAMEND $ff99 #define RAMSTART $ff9c #define GETKEY $ff9f #define IECTIMEOUT $ffa2 #define IECIN $ffa5 #define IECOUT $ffa8 #define UNTALK $ffab #define UNLISTEN $ffae #define LISTEN $ffb1 #define TALK $ffb4 #define GETST $ffb7 #define SETFPAR $ffba #define SETFNPAR $ffbd #define OPEN $ffc0 #define CLOSE $ffc3 #define CHKIN $ffc6 #define CKOUT $ffc9 #define CLRCH $ffcc #define BASIN $ffcf #define BSOUT $ffd2 #define LOAD $ffd5 #define SAVE $ffd8 #define SETTI $ffdb #define GETTI $ffde #define GETSTP $ffe1 #define GET $ffe4 #define CLALL $ffe7 #define INCTI $ffea #define SCREEN $ffed #define CURSOR $fff0 #define GETIOBASE $fff3 /* Terminal-Commands */ #define TC_SCO 8 #define TC_SCF 9 #define TC_LF 13 /*10*/ #define TC_CR 13 #define TC_LCH $0e #define TC_REV 18 #define TC_F1 $85 #define TC_F3 $86 #define TC_F5 $87 #define TC_F7 $88 #define TC_F2 $89 #define TC_F4 $8a #define TC_F6 $8b #define TC_F8 $8c #define TC_HCH $8e #define TC_REO $92 #define TC_FF $93 #define TC_HELLGRUEN $99 #define TC_CRL $9d xa-2.3.8/tests/cpktest/de.ok0000644000031500000010000000430512447655041015222 0ustar spectrestaff  ž2064 Ìÿ ¶ …©—   ©Æ   ©â   ®Ä© ͽ©ö   ©î   ©   ®Å© ͽ©    äÿðû¢Ýðèàö°í sLŠ ª½€H½H`. e á"býÁÑ…‰†‡ŒˆŠ‹“ (F1) PROGRAMME ZUSAMMENPACKEN (F2) ARCHIV AUSPACKEN (F3) QUELLPFAD: (F4) QUELLDEVICE: (F5) ZIELPFAD : (F6) ZIELDEVICE : (F7) QUELLDIRECTORY (F8) QUELLE UND ZIEL TAUSCHEN IHRE EINGABE BITTE ü °,© !  ÉÐ# Ö û©Á   ­!®  ͽ© Òÿ \© Ãÿ`©§   L— UNGUELTIGE ARCHIV-VERSIONARCHIV HATTE BYTES #©© Òÿ „û  °4¤û™$æûÉð ÒÿLç ©„    \ÉJЩƠ  ©ÿ…ü ´ g ° Lƒ ©½   ©…ü  °1É÷Ð#  Éð"  $üâ­ ÎÐõL. $üÐ L.  " © Ãÿ©œ   ­® ͽ© Òÿ(` DATEI AUSPACKEN (J/N)?ERGIBT BYTES #îÐî` „¹î™ðÈÉ:ðÉ/ЄÀ(馠¹$èÈÉÐôÊŠ¢  ½ÿ©®Å  ºÿ Àÿ°  ` ¹ÆðÈÀ(öÀð!˜¢Æ  ½ÿ©®Ä  ºÿ Àÿ° a ° g `8` ¤ ­ð, Í °© ©…û Ï…ý†þ g æû¥ûÍí " © Ãÿ g L`¥`©¬    „ü±ý Òÿ ¤üÈÉÐï ¶ ° ”  ° s L‰ š © Ãÿ©÷ © © Òÿ` cOPYING  „¹Æ™ðÈÉ:ðÉ/ЄÀ(馠±ýèÈÉÐõÊŠ¢  ½ÿ©®Ä  ºÿ Àÿ° g `î Ðî!`¬Ìð¹î`­ð8`©¢ Æÿ©… ÏÿH¥ð©L Òÿ¦© ͽ© Òÿh ý ¬™ÈŒÈð¥ðÒ¥ ÌÿL ©`®ðèÐH š hL ÍðH š hî`©`­ð-ɰ­É÷ð ­ ÎÐõ`©÷ ­ ­ ©` ¹îðÈÀ(öÀð$˜¢î  ½ÿ©®Å  ºÿ Àÿ° ­Å g °  `8`©`¬™ÈŒÈÌÐH " h`¢ Éÿ¬Ìð&¹ Òÿ¥ð˜H©W ç¥ @ ç© çh¨ « ÈL* © Ìÿ`­ÄLj ­ÅH Ìÿ© Òÿh ´ÿ©o –ÿ©… ¥ÿH Òÿ ¥ÿÉð Òÿ¥ðò «ÿhÉ0Ð`8`L}©©“ Òÿ b Õó¥º ´ÿ¥¹ –ÿ©… „û ¥ÿ…ü¤ÐÒ ¥ÿÆûÐð¦ü ͽ© Òÿ ¥ÿÉðºÉÐLY ÒÿÉ"Ðë­ Ï…ý†þ „û ¥ÿ Òÿ¤ûÉ"ð‘ýÈÀë©,‘ýÈ„û ¥ÿ Òÿ¤ûÉ ðò…ü‘ýÈ©‘ýª ¥ÿ ÒÿÉ Ðõà<ð© Òÿ© Òÿ¥ü ƒ ¥ÿÉÐùð ¥ÿ¦Ðªð ÒÿLY© Òÿ äÿð \ ðLÄ BöL\ÉPðÉSð`©­    \ÉJ𩽠  `©Æ   î`JA/NEIN’NEIN ’JA ¢† & &…¦ & &e…Še…©$e…H©e…ªh`©“ Òÿ b Õó¥º ´ÿ¥¹ –ÿ©… „û ¥ÿ…ü¤Ð2 ¥ÿÆûÐð¦ü ͽ© Òÿ ¥ÿ¦Ðªð ÒÿL5© Òÿ äÿð \ Ðà BöL\ äÿðû`©$¢† ¹Æð É:ð ÈÀ(ò©:è ¹ÆðÉ:ðÉ/ІèÈÀ(è¦è©*è©.è©*芢  ½ÿ©®Ä LºÿîÄ­ÄÉ ©Ä`îÅ­ÅÉ ©Å`©    `¥ ¹™Æð ÈÀ'󩙯` BITTE NEUEN QUELLPFAD EINGEBEN: ©B    `¥ ¹™îð ÈÀ'ó©™î` BITTE NEUEN ZIELPFAD EINGEBEN: ­Ä®ÅŽÄÅ¢½ÆH½îÆhîèà(í`©Æî¥ºÉÉ ©ÄÅ`…"„# ±"ð Òÿæ"Ðóæ#Ðï`© Ð!Щ™ Òÿ`xa-2.3.8/tests/cpktest/deutsch.l0000644000031500000010000001046612447655041016120 0ustar spectrestaffbasicend, 0x080b, 1, 0x0000 iniscreen, 0x10b6, 1, 0x0000 inipar, 0x1085, 1, 0x0000 menu1, 0x0819, 2, 0x0000 m1atxt, 0x0897, 2, 0x0000 Txtout, 0x10a0, 1, 0x0000 quellpfad, 0x10c6, 1, 0x0000 m1btxt, 0x08e2, 2, 0x0000 quelldrv, 0x10c4, 1, 0x0000 m1ctxt, 0x08f6, 2, 0x0000 zielpfad, 0x10ee, 1, 0x0000 m1dtxt, 0x0908, 2, 0x0000 zieldrv, 0x10c5, 1, 0x0000 m1etxt, 0x091c, 2, 0x0000 next, 0x085a, 2, 0x0000 l1, 0x0861, 2, 0x0000 befkeys, 0x088f, 2, 0x0000 exe, 0x086d, 2, 0x0000 Anzbefs, 0x0008, 2, 0x0000 exec, 0x0873, 2, 0x0000 madr, 0x087f, 2, 0x0000 pack, 0x0b2f, 1, 0x0000 unpack, 0x0966, 1, 0x0000 quelle, 0x0fe2, 1, 0x0000 ziel, 0x1023, 1, 0x0000 switch, 0x1063, 1, 0x0000 dir, 0x0efe, 1, 0x0000 qdrv, 0x0fc2, 1, 0x0000 zdrv, 0x0fd2, 1, 0x0000 openarcrd, 0x0afc, 1, 0x0000 cls, 0x0997, 12, 0x0000 rcnt, 0x1320, 1, 0x0000 rbyte, 0x0c06, 1, 0x0000 verr, 0x099d, 12, 0x0000 loop, 0x097a, 12, 0x0000 unpackfile, 0x09d6, 1, 0x0000 t1, 0x09c1, 12, 0x0000 waitkey, 0x0f5c, 1, 0x0000 verrtxt, 0x09a7, 12, 0x0000 wcnt, 0x131e, 1, 0x0000 l1, 0x09e7, 15, 0x0000 endx, 0x0a20, 15, 0x0000 filetab, 0x1324, 1, 0x0000 endnam, 0x09fd, 15, 0x0000 ask, 0x0a84, 15, 0x0000 nounpack, 0x0a23, 15, 0x0000 tok, 0x0ec6, 1, 0x0000 fxopen, 0x0ab4, 1, 0x0000 Getzst, 0x0d67, 1, 0x0000 xa, 0x0a2a, 15, 0x0000 lo, 0x0a2e, 15, 0x0000 end, 0x0a83, 15, 0x0000 tno, 0x0ebd, 1, 0x0000 cls, 0x0a64, 15, 0x0000 xb, 0x0a5a, 15, 0x0000 wxanz, 0x121a, 1, 0x0000 wxbyt, 0x1219, 1, 0x0000 ly, 0x0a4c, 15, 0x0000 wbyte, 0x0d0c, 1, 0x0000 wbuf, 0x0d22, 1, 0x0000 t1, 0x0a9c, 15, 0x0000 incwcnt, 0x0aab, 1, 0x0000 l1, 0x0ab3, 20, 0x0000 l1, 0x0ab8, 21, 0x0000 l2, 0x0acf, 21, 0x0000 l1a, 0x0ac9, 21, 0x0000 l1b, 0x0acb, 21, 0x0000 l3, 0x0ad3, 21, 0x0000 err, 0x0afb, 21, 0x0000 clrwrbuf, 0x0d03, 1, 0x0000 l0, 0x0afe, 22, 0x0000 l1, 0x0b08, 22, 0x0000 err, 0x0b2d, 22, 0x0000 Getqst, 0x0d61, 1, 0x0000 clrrdbuf, 0x0c67, 1, 0x0000 getlist, 0x0da4, 1, 0x0000 anzfiles, 0x1116, 1, 0x0000 end, 0x0b63, 23, 0x0000 openarcwr, 0x0ccd, 1, 0x0000 cls, 0x0b5b, 23, 0x0000 l1, 0x0b45, 23, 0x0000 setfadr, 0x0ecf, 1, 0x0000 packfile, 0x0b67, 1, 0x0000 lft, 0x0bac, 24, 0x0000 l1, 0x0b70, 24, 0x0000 fopen, 0x0bb6, 1, 0x0000 le, 0x0b97, 24, 0x0000 clrwxbyt, 0x0c94, 1, 0x0000 l2, 0x0b89, 24, 0x0000 l3, 0x0b94, 24, 0x0000 wxbyte, 0x0c73, 1, 0x0000 savwxbyt, 0x0c9a, 1, 0x0000 l1, 0x0bba, 26, 0x0000 l2, 0x0bd1, 26, 0x0000 l1a, 0x0bcb, 26, 0x0000 l1b, 0x0bcd, 26, 0x0000 l3, 0x0bd5, 26, 0x0000 err, 0x0bfc, 26, 0x0000 incrcnt, 0x0bfd, 1, 0x0000 l1, 0x0c05, 27, 0x0000 ro, 0x121c, 1, 0x0000 ri, 0x121b, 1, 0x0000 leerbuf, 0x0c16, 28, 0x0000 rb, 0x121e, 1, 0x0000 rf, 0x121d, 1, 0x0000 ldbuf, 0x0c1d, 28, 0x0000 lok, 0x0c2e, 28, 0x0000 l0, 0x0c47, 28, 0x0000 le, 0x0c5c, 28, 0x0000 add, 0x0c8d, 31, 0x0000 ad2, 0x0c83, 31, 0x0000 adx, 0x0c90, 31, 0x0000 nosav, 0x0ccc, 33, 0x0000 savs, 0x0cb6, 33, 0x0000 l1, 0x0caa, 33, 0x0000 l0, 0x0ccf, 34, 0x0000 l1, 0x0cd9, 34, 0x0000 err, 0x0d01, 34, 0x0000 wi, 0x1117, 1, 0x0000 wo, 0x1118, 1, 0x0000 wb, 0x1119, 1, 0x0000 nowr, 0x0d21, 36, 0x0000 l1, 0x0d2a, 37, 0x0000 end, 0x0d55, 37, 0x0000 l0, 0x0d4e, 37, 0x0000 Getst, 0x0d6a, 1, 0x0000 l1, 0x0d87, 38, 0x0000 l2, 0x0d95, 38, 0x0000 err, 0x0d9f, 38, 0x0000 l4x, 0x0da1, 39, 0x0000 l4, 0x0e7d, 39, 0x0000 setdirnam, 0x0f62, 1, 0x0000 l0, 0x0dc4, 39, 0x0000 l1, 0x0dc6, 39, 0x0000 la, 0x0de0, 39, 0x0000 l3x, 0x0dee, 39, 0x0000 l3, 0x0e59, 39, 0x0000 lb, 0x0e01, 39, 0x0000 lc, 0x0e16, 39, 0x0000 ld, 0x0e1b, 39, 0x0000 lf, 0x0e32, 39, 0x0000 lg, 0x0e46, 39, 0x0000 testkeys, 0x0e83, 1, 0x0000 lh, 0x0e50, 39, 0x0000 l2, 0x0e69, 39, 0x0000 l5, 0x0e76, 39, 0x0000 ok, 0x0e8c, 40, 0x0000 t1, 0x0ead, 40, 0x0000 ja, 0x0ea2, 40, 0x0000 l0, 0x0f19, 45, 0x0000 l1, 0x0f1b, 45, 0x0000 l4, 0x0f56, 45, 0x0000 l3, 0x0f35, 45, 0x0000 l2, 0x0f45, 45, 0x0000 l5, 0x0f52, 45, 0x0000 p1, 0x0014, 46, 0x0000 l1, 0x0f6d, 46, 0x0000 nodp, 0x0f7b, 46, 0x0000 dp, 0x0f81, 46, 0x0000 dp1, 0x0f83, 46, 0x0000 end, 0x0f9b, 46, 0x0000 l2a, 0x0f93, 46, 0x0000 l2, 0x0f95, 46, 0x0000 ok, 0x0fd1, 47, 0x0000 ok, 0x0fe1, 48, 0x0000 quelltxt, 0x1001, 49, 0x0000 q1, 0x0fee, 49, 0x0000 end, 0x1000, 49, 0x0000 quelltxt, 0x1042, 51, 0x0000 q1, 0x102f, 51, 0x0000 end, 0x1041, 51, 0x0000 l1, 0x1071, 53, 0x0000 noval, 0x1097, 54, 0x0000 ok, 0x1099, 54, 0x0000 p, 0x0022, 55, 0x0000 l1, 0x10a4, 55, 0x0000 le, 0x10b5, 55, 0x0000 sysmem, 0x1324, 1, 0x0000 ecnt, 0x1322, 1, 0x0000 ende, 0x10c4, 1, 0x0000 xa-2.3.8/tests/cpktest/eng.ok0000644000031500000010000000432312447655015015404 0ustar spectrestaff  ž2064 Ìÿ Ä “©—  ®©Ô  ®©á  ®®Ò© ͽ©ö  ®©ü  ®©   ®®Ó© ͽ©#  ® äÿðû¢Ýðèàö°í sLŠ ª½€H½H`1 o ä*pÄÔ…‰†‡ŒˆŠ‹“ (F1) PACK PROGRAMMS (F2) EXTRACT FROM ARCHIVE (F3) SOURCEPATH/ARC: (F4) SOURCEDEVICE: (F5) TARGETPATH/ARC: (F6) TARGETDEVICE : (F7) SOURCEDIRECTORY (F8) EXCHANGE TARGET AND SOURCE YOUR CHOICE PLEASE ÿ °,©./ ÉÐ# Ý û©É  ®­/®. ͽ© Òÿ _© Ãÿ`©±  ®L¡ UNKNOWN ARCHIVE VERSIONARCHIVE HAD BYTES #©,-© Òÿ „û °4¤û™2æûÉð ÒÿLî ©‹  ® _ÉJЩɠ ®©ÿ…ü · j ° LŠ ©À  ®©…ü °1É÷Ð# (Éð" '$üâ­'  Î(ÐõL5 $üÐ  L5  % © Ãÿ©   ®­-®, ͽ© Òÿ(` EXTRACT FILE (Y/N)?GIVES BYTES #î,Ðî-` „¹ü™ðÈÉ:ðÉ/ЄÀ(馠¹2èÈÉÐôÊŠ¢  ½ÿ©®Ó  ºÿ Àÿ°  ` ¹ÔðÈÀ(öÀð!˜¢Ô  ½ÿ©®Ò  ºÿ Àÿ° d ° j `8` § ­$ð, Ð °©  ©…û Ò…ý†þ j æû¥ûÍ$í % © Ãÿ j L`¥`©¯  ® „ü±ý Òÿ  ¤üÈÉÐï ¹ ° — ° v LŒ © Ãÿ©÷  ©  © Òÿ` cOPYING  „¹Ô™ðÈÉ:ðÉ/ЄÀ(馠±ýèÈÉÐõÊŠ¢  ½ÿ©®Ò  ºÿ Àÿ° j `î.Ðî/`¬*Ì)ð¹,î*`­+ð8`©)*¢ Æÿ©… ÏÿH¥ð©L Òÿ¦© ͽ© Òÿh ¬)™,ÈŒ)Èð¥ðÒ¥+ ÌÿL ©)*+`®(ðèÐH hL Í'ðH h'î(`©(`­(ð-ɰ­'É÷ð ­'  Î(Ðõ`©÷  ­(  ­'  ©(` ¹üðÈÀ(öÀð$˜¢ü  ½ÿ©®Ó  ºÿ Àÿ° ­Ó j °  `8`©%&`¬%™'ÈŒ%ÈÌ&ÐH % h`¢ Éÿ¬&Ì%ð&¹' Òÿ¥ð˜H©W ç¥ @ ç© çh¨ ® ÈL- ©%& Ìÿ`­ÒLm ­ÓH Ìÿ© Òÿh ´ÿ©o –ÿ©… ¥ÿH Òÿ ¥ÿÉð Òÿ¥ðò «ÿhÉ0Ð`8`L€©$©“ Òÿ e Õó¥º ´ÿ¥¹ –ÿ©… „û ¥ÿ…ü¤ÐÒ ¥ÿÆûÐð¦ü ͽ© Òÿ ¥ÿÉðºÉÐL\ ÒÿÉ"Ðë­$ Ò…ý†þ „û ¥ÿ Òÿ¤ûÉ"ð‘ýÈÀë©,‘ýÈ„û ¥ÿ Òÿ¤ûÉ ðò…ü‘ýÈ©‘ýª ¥ÿ ÒÿÉ Ðõà<ð© Òÿ© Òÿ¥ü † ¥ÿÉÐùð ¥ÿ¦Ðªð ÒÿL\© Òÿ äÿð _ ðLÇ BöL_ÉPðÉSð`©°  ® _ÉJð©À  ®`©É  ®î$`YES/NO ’NO ’YES ¢† & &…¦ & &e…Še…©2e…H©e…ªh`©“ Òÿ e Õó¥º ´ÿ¥¹ –ÿ©… „û ¥ÿ…ü¤Ð2 ¥ÿÆûÐð¦ü ͽ© Òÿ ¥ÿ¦Ðªð ÒÿL8© Òÿ äÿð _ Ðà BöL_ äÿðû`©$¢† ¹Ôð É:ð ÈÀ(ò©:è ¹ÔðÉ:ðÉ/ІèÈÀ(è¦è©*è©.è©*芢  ½ÿ©®Ò LºÿîÒ­ÒÉ ©Ò`îÓ­ÓÉ ©Ó`©  ® `¥ ¹™Ôð ÈÀ'ó©™Ô` PLEASE INPUT NEW SOURCEPATH/ARCHIVE: ©J  ® `¥ ¹™üð ÈÀ'ó©™ü` PLEASE INPUT NEW TARGETPATH/ARCHIVE: ­Ò®ÓŽÒÓ¢½ÔH½üÔhüèà(í`©Ôü¥ºÉÉ ©ÒÓ`…"„# ±"ð Òÿæ"Ðóæ#Ðï`© Ð!Щ™ Òÿ`xa-2.3.8/tests/cpktest/english.l0000644000031500000010000001046612447655402016113 0ustar spectrestaffbasicend, 0x080b, 1, 0x0000 iniscreen, 0x10c4, 1, 0x0000 inipar, 0x1093, 1, 0x0000 menu1, 0x0819, 2, 0x0000 m1atxt, 0x0897, 2, 0x0000 Txtout, 0x10ae, 1, 0x0000 quellpfad, 0x10d4, 1, 0x0000 m1btxt, 0x08e1, 2, 0x0000 quelldrv, 0x10d2, 1, 0x0000 m1ctxt, 0x08f6, 2, 0x0000 zielpfad, 0x10fc, 1, 0x0000 m1dtxt, 0x090d, 2, 0x0000 zieldrv, 0x10d3, 1, 0x0000 m1etxt, 0x0923, 2, 0x0000 next, 0x085a, 2, 0x0000 l1, 0x0861, 2, 0x0000 befkeys, 0x088f, 2, 0x0000 exe, 0x086d, 2, 0x0000 Anzbefs, 0x0008, 2, 0x0000 exec, 0x0873, 2, 0x0000 madr, 0x087f, 2, 0x0000 pack, 0x0b32, 1, 0x0000 unpack, 0x0970, 1, 0x0000 quelle, 0x0fe5, 1, 0x0000 ziel, 0x102b, 1, 0x0000 switch, 0x1071, 1, 0x0000 dir, 0x0f01, 1, 0x0000 qdrv, 0x0fc5, 1, 0x0000 zdrv, 0x0fd5, 1, 0x0000 openarcrd, 0x0aff, 1, 0x0000 cls, 0x09a1, 12, 0x0000 rcnt, 0x132e, 1, 0x0000 rbyte, 0x0c09, 1, 0x0000 verr, 0x09a7, 12, 0x0000 loop, 0x0984, 12, 0x0000 unpackfile, 0x09dd, 1, 0x0000 t1, 0x09c9, 12, 0x0000 waitkey, 0x0f5f, 1, 0x0000 verrtxt, 0x09b1, 12, 0x0000 wcnt, 0x132c, 1, 0x0000 l1, 0x09ee, 15, 0x0000 endx, 0x0a27, 15, 0x0000 filetab, 0x1332, 1, 0x0000 endnam, 0x0a04, 15, 0x0000 ask, 0x0a8b, 15, 0x0000 nounpack, 0x0a2a, 15, 0x0000 tok, 0x0ec9, 1, 0x0000 fxopen, 0x0ab7, 1, 0x0000 Getzst, 0x0d6a, 1, 0x0000 xa, 0x0a31, 15, 0x0000 lo, 0x0a35, 15, 0x0000 end, 0x0a8a, 15, 0x0000 tno, 0x0ec0, 1, 0x0000 cls, 0x0a6b, 15, 0x0000 xb, 0x0a61, 15, 0x0000 wxanz, 0x1228, 1, 0x0000 wxbyt, 0x1227, 1, 0x0000 ly, 0x0a53, 15, 0x0000 wbyte, 0x0d0f, 1, 0x0000 wbuf, 0x0d25, 1, 0x0000 t1, 0x0aa0, 15, 0x0000 incwcnt, 0x0aae, 1, 0x0000 l1, 0x0ab6, 20, 0x0000 l1, 0x0abb, 21, 0x0000 l2, 0x0ad2, 21, 0x0000 l1a, 0x0acc, 21, 0x0000 l1b, 0x0ace, 21, 0x0000 l3, 0x0ad6, 21, 0x0000 err, 0x0afe, 21, 0x0000 clrwrbuf, 0x0d06, 1, 0x0000 l0, 0x0b01, 22, 0x0000 l1, 0x0b0b, 22, 0x0000 err, 0x0b30, 22, 0x0000 Getqst, 0x0d64, 1, 0x0000 clrrdbuf, 0x0c6a, 1, 0x0000 getlist, 0x0da7, 1, 0x0000 anzfiles, 0x1124, 1, 0x0000 end, 0x0b66, 23, 0x0000 openarcwr, 0x0cd0, 1, 0x0000 cls, 0x0b5e, 23, 0x0000 l1, 0x0b48, 23, 0x0000 setfadr, 0x0ed2, 1, 0x0000 packfile, 0x0b6a, 1, 0x0000 lft, 0x0baf, 24, 0x0000 l1, 0x0b73, 24, 0x0000 fopen, 0x0bb9, 1, 0x0000 le, 0x0b9a, 24, 0x0000 clrwxbyt, 0x0c97, 1, 0x0000 l2, 0x0b8c, 24, 0x0000 l3, 0x0b97, 24, 0x0000 wxbyte, 0x0c76, 1, 0x0000 savwxbyt, 0x0c9d, 1, 0x0000 l1, 0x0bbd, 26, 0x0000 l2, 0x0bd4, 26, 0x0000 l1a, 0x0bce, 26, 0x0000 l1b, 0x0bd0, 26, 0x0000 l3, 0x0bd8, 26, 0x0000 err, 0x0bff, 26, 0x0000 incrcnt, 0x0c00, 1, 0x0000 l1, 0x0c08, 27, 0x0000 ro, 0x122a, 1, 0x0000 ri, 0x1229, 1, 0x0000 leerbuf, 0x0c19, 28, 0x0000 rb, 0x122c, 1, 0x0000 rf, 0x122b, 1, 0x0000 ldbuf, 0x0c20, 28, 0x0000 lok, 0x0c31, 28, 0x0000 l0, 0x0c4a, 28, 0x0000 le, 0x0c5f, 28, 0x0000 add, 0x0c90, 31, 0x0000 ad2, 0x0c86, 31, 0x0000 adx, 0x0c93, 31, 0x0000 nosav, 0x0ccf, 33, 0x0000 savs, 0x0cb9, 33, 0x0000 l1, 0x0cad, 33, 0x0000 l0, 0x0cd2, 34, 0x0000 l1, 0x0cdc, 34, 0x0000 err, 0x0d04, 34, 0x0000 wi, 0x1125, 1, 0x0000 wo, 0x1126, 1, 0x0000 wb, 0x1127, 1, 0x0000 nowr, 0x0d24, 36, 0x0000 l1, 0x0d2d, 37, 0x0000 end, 0x0d58, 37, 0x0000 l0, 0x0d51, 37, 0x0000 Getst, 0x0d6d, 1, 0x0000 l1, 0x0d8a, 38, 0x0000 l2, 0x0d98, 38, 0x0000 err, 0x0da2, 38, 0x0000 l4x, 0x0da4, 39, 0x0000 l4, 0x0e80, 39, 0x0000 setdirnam, 0x0f65, 1, 0x0000 l0, 0x0dc7, 39, 0x0000 l1, 0x0dc9, 39, 0x0000 la, 0x0de3, 39, 0x0000 l3x, 0x0df1, 39, 0x0000 l3, 0x0e5c, 39, 0x0000 lb, 0x0e04, 39, 0x0000 lc, 0x0e19, 39, 0x0000 ld, 0x0e1e, 39, 0x0000 lf, 0x0e35, 39, 0x0000 lg, 0x0e49, 39, 0x0000 testkeys, 0x0e86, 1, 0x0000 lh, 0x0e53, 39, 0x0000 l2, 0x0e6c, 39, 0x0000 l5, 0x0e79, 39, 0x0000 ok, 0x0e8f, 40, 0x0000 t1, 0x0eb0, 40, 0x0000 ja, 0x0ea5, 40, 0x0000 l0, 0x0f1c, 45, 0x0000 l1, 0x0f1e, 45, 0x0000 l4, 0x0f59, 45, 0x0000 l3, 0x0f38, 45, 0x0000 l2, 0x0f48, 45, 0x0000 l5, 0x0f55, 45, 0x0000 p1, 0x0014, 46, 0x0000 l1, 0x0f70, 46, 0x0000 nodp, 0x0f7e, 46, 0x0000 dp, 0x0f84, 46, 0x0000 dp1, 0x0f86, 46, 0x0000 end, 0x0f9e, 46, 0x0000 l2a, 0x0f96, 46, 0x0000 l2, 0x0f98, 46, 0x0000 ok, 0x0fd4, 47, 0x0000 ok, 0x0fe4, 48, 0x0000 quelltxt, 0x1004, 49, 0x0000 q1, 0x0ff1, 49, 0x0000 end, 0x1003, 49, 0x0000 quelltxt, 0x104a, 51, 0x0000 q1, 0x1037, 51, 0x0000 end, 0x1049, 51, 0x0000 l1, 0x107f, 53, 0x0000 noval, 0x10a5, 54, 0x0000 ok, 0x10a7, 54, 0x0000 p, 0x0022, 55, 0x0000 l1, 0x10b2, 55, 0x0000 le, 0x10c3, 55, 0x0000 sysmem, 0x1332, 1, 0x0000 ecnt, 0x1330, 1, 0x0000 ende, 0x10d2, 1, 0x0000 xa-2.3.8/tests/cpktest/pack_eng.a650000600000031500000010000004722612447654537016375 0ustar spectrestaff #include "c64def.def" #define Tout(a) .(:lda #a:jsr Txtout:.) #define Aout(a) .(:lda #b:jsr Txtout:jmp c:b .byt a,0:c .) #define Ibout(a) .(:ldx a:lda #0:jsr INTOUT:.) #define Iout(a) .(:ldx a:lda a+1:jsr INTOUT:.) #define PFADLEN 40 #define FN_WR 3 #define FN_RD 4 #define XCODE $f7 #define Version 1 .( .word $0801 *=$0801 .word basicend,10 .byt $9e,"2064",0 ;sys $0810 basicend .word 0 .byt 0,0,0 .( jsr CLRCH jsr iniscreen jsr inipar menu1 Tout(m1atxt) Tout(quellpfad) Tout(m1btxt) Ibout(quelldrv) Tout(m1ctxt) Tout(zielpfad) Tout(m1dtxt) Ibout(zieldrv) Tout(m1etxt) next jsr GET beq next ldx #0 l1 cmp befkeys,x beq exe inx cpx #Anzbefs bcc l1 bcs next exe jsr exec jmp menu1 exec txa asl tax lda madr+1,x pha lda madr,x pha rts madr .word pack-1,unpack-1,quelle-1,ziel-1,switch-1,dir-1,qdrv-1,zdrv-1 befkeys .asc TC_F1,TC_F2,TC_F3,TC_F5,TC_F8,TC_F7,TC_F4,TC_F6 Anzbefs =8 m1atxt .asc TC_LCH,TC_SCO,TC_FF,TC_LF,TC_LF .asc "(F1) PACK PROGRAMMS",TC_CR,TC_LF .asc "(F2) EXTRACT FROM ARCHIVE",TC_CR,TC_LF .asc "(F3) SOURCEPATH/ARC:",0 m1btxt .asc TC_CR,TC_LF .asc "(F4) SOURCEDEVICE:",0 m1ctxt .asc TC_CR,TC_LF .asc "(F5) TARGETPATH/ARC:",0 m1dtxt .asc TC_CR,TC_LF .asc "(F6) TARGETDEVICE :",0 m1etxt .asc TC_CR,TC_LF .asc "(F7) SOURCEDIRECTORY",TC_CR,TC_LF .asc "(F8) EXCHANGE TARGET AND SOURCE",TC_CR,TC_LF .asc "YOUR CHOICE PLEASE",TC_CR,0 .) unpack .( jsr openarcrd bcs cls lda #0 sta rcnt sta rcnt+1 jsr rbyte cmp #Version bne verr loop jsr unpackfile bcc loop Tout(t1) lda rcnt+1 ldx rcnt jsr INTOUT lda #TC_CR jsr BSOUT jsr waitkey cls lda #FN_RD jsr CLOSE rts verr Tout(verrtxt) jmp cls verrtxt .asc "UNKNOWN ARCHIVE VERSION",0 t1 .asc "ARCHIVE HAD BYTES #",0 .) unpackfile .( lda #0 sta wcnt sta wcnt+1 lda #TC_CR jsr BSOUT ldy #0 sty P1 l1 jsr rbyte bcs endx ldy P1 sta filetab,y inc P1 cmp #0 beq endnam jsr BSOUT jmp l1 endnam Tout(ask) jsr waitkey cmp #"J" bne nounpack Tout(tok) lda #<-1 sta P1+1 jsr fxopen jsr Getzst bcs xa bcc lo endx jmp end nounpack Tout(tno) xa lda #0 sta P1+1 lo jsr rbyte bcs cls cmp #XCODE bne xb jsr rbyte sta wxanz cmp #0 clc beq cls jsr rbyte sta wxbyt bit P1+1 bpl lo ly lda wxbyt jsr wbyte dec wxanz bne ly jmp lo xb bit P1+1 bpl lo jsr wbyte jmp lo cls php jsr wbuf lda #FN_WR jsr CLOSE Tout(t1) lda wcnt+1 ldx wcnt jsr INTOUT lda #TC_CR jsr BSOUT plp end rts ask .asc TC_CR,"EXTRACT FILE (Y/N)?",0 t1 .asc "GIVES BYTES #",0 .) incwcnt .( inc wcnt bne l1 inc wcnt+1 l1 rts .) fxopen .( ldy #0 sty INT l1 lda zielpfad,y sta INBUF,y beq l2 iny cmp #":" beq l1a cmp #"/" bne l1b l1a sty INT l1b cpy #PFADLEN bcc l1 l2 ldx INT ldy #0 l3 lda filetab,y sta INBUF,x inx iny cmp #0 bne l3 dex txa ldx #INBUF jsr SETFNPAR lda #FN_WR ldx zieldrv ldy #1 jsr SETFPAR jsr OPEN bcs err jsr clrwrbuf clc err rts .) openarcrd .( ldy #0 l0 lda quellpfad,y beq l1 iny cpy #PFADLEN bcc l0 l1 cpy #0 beq err tya ldx #quellpfad jsr SETFNPAR lda #FN_RD ldx quelldrv ldy #0 jsr SETFPAR jsr OPEN bcs err jsr Getqst bcs err jsr clrrdbuf clc rts err sec rts .) pack .( jsr getlist lda anzfiles beq end jsr openarcwr bcs cls lda #Version jsr wbyte lda #0 sta P1 l1 jsr setfadr sta P2 stx P2+1 jsr packfile inc P1 lda P1 cmp anzfiles bcc l1 jsr wbuf cls lda #FN_WR jsr CLOSE jsr Getzst end jmp LINEIN:rts .) packfile .( Tout(lft) ldy #0 l1 sty P1+1 lda (P2),y jsr BSOUT jsr wbyte ldy P1+1 iny cmp #0 bne l1 jsr fopen bcs le jsr clrwxbyt l2 jsr rbyte bcs l3 jsr wxbyte jmp l2 l3 jsr savwxbyt le lda #FN_RD jsr CLOSE lda #XCODE jsr wbyte lda #0 jsr wbyte lda #TC_CR jsr BSOUT rts lft .asc TC_CR,"cOPYING ",0 .) fopen .( ldy #0 sty INT l1 lda quellpfad,y sta INBUF,y beq l2 iny cmp #":" beq l1a cmp #"/" bne l1b l1a sty INT l1b cpy #PFADLEN bcc l1 l2 ldx INT ldy #0 l3 lda (P2),y sta INBUF,x inx iny cmp #0 bne l3 dex txa ldx #INBUF jsr SETFNPAR lda #FN_RD ldx quelldrv ldy #0 jsr SETFPAR jsr OPEN bcs err jsr clrrdbuf clc err rts .) incrcnt .( inc rcnt bne l1 inc rcnt+1 l1 rts .) rbyte .( ldy ro cpy ri beq leerbuf lda rb,y inc ro clc rts leerbuf lda rf beq ldbuf sec rts ldbuf lda #0 sta ri sta ro ldx #FN_RD jsr CHKIN lda #0 sta STATUS lok jsr BASIN pha lda STATUS beq l0 lda #"L" jsr BSOUT Ibout($90) lda #TC_CR jsr BSOUT l0 pla jsr incrcnt ldy ri sta rb,y iny sty ri iny ;cpy ro beq le lda STATUS beq lok le lda STATUS sta rf jsr CLRCH jmp rbyte .) clrrdbuf .( lda #0 sta ri sta ro sta rf rts .) wxbyte .( ldx wxanz beq add inx bne ad2 pha jsr savwxbyt pla jmp add ad2 cmp wxbyt beq adx pha jsr savwxbyt pla add sta wxbyt adx inc wxanz rts .) clrwxbyt .( lda #0 sta wxanz rts .) savwxbyt .( lda wxanz beq nosav cmp #4 bcs savs lda wxbyt cmp #XCODE beq savs l1 lda wxbyt jsr wbyte dec wxanz bne l1 rts savs lda #XCODE jsr wbyte lda wxanz jsr wbyte lda wxbyt jsr wbyte lda #0 sta wxanz nosav rts .) openarcwr .( ldy #0 l0 lda zielpfad,y beq l1 iny cpy #PFADLEN bcc l0 l1 cpy #0 beq err tya ldx #zielpfad jsr SETFNPAR lda #FN_WR ldx zieldrv ldy #1 jsr SETFPAR jsr OPEN bcs err lda zieldrv jsr Getzst bcs err jsr clrwrbuf clc rts err sec rts .) clrwrbuf .( lda #0 sta wi sta wo rts .) wbyte .( ldy wi sta wb,y iny sty wi iny cpy wo bne nowr pha jsr wbuf pla nowr rts .) wbuf .( ldx #FN_WR jsr CKOUT ldy wo l1 cpy wi beq end lda wb,y jsr BSOUT lda STATUS beq l0 tya pha lda #"W" jsr $e716 lda $90 ora #$40 jsr $e716 lda #TC_CR jsr $e716 pla tay l0 jsr incwcnt iny jmp l1 end lda #0 sta wi sta wo jsr CLRCH rts .) .( &Getqst lda quelldrv jmp Getst &Getzst lda zieldrv &Getst pha jsr CLRCH lda #TC_CR jsr BSOUT pla jsr TALK lda #15+$60 jsr SECTALK lda #0 sta STATUS jsr IECIN pha jsr BSOUT l1 jsr IECIN cmp #0 beq l2 jsr BSOUT lda STATUS beq l1 l2 jsr UNTALK pla cmp #"0" bne err clc rts err sec rts .) /* showlist .( lda #0 sta P1 l1 lda P1 cmp anzfiles bcs le jsr setfadr lda #TC_CR jsr BSOUT lda INT ldy INT+1 jsr Txtout inc P1 jmp l1 le rts .) */ .( l4x jmp l4 &getlist lda #0 sta anzfiles lda #TC_FF jsr BSOUT jsr setdirnam jsr SENDNAM lda DEVADR jsr TALK lda SECADR jsr SECTALK lda #0 sta STATUS ldy #3 l0 sty P1 l1 jsr IECIN sta P1+1 ldy STATUS bne l4x jsr IECIN dec P1 bne l1 ldx P1+1 jsr INTOUT lda #" " jsr BSOUT la jsr IECIN cmp #0 beq l4x cmp #TC_REV bne l3x jmp l3 l3x jsr BSOUT cmp #34 bne la lda anzfiles jsr setfadr sta P2 stx P2+1 ldy #0 lb sty P1 jsr IECIN jsr BSOUT ldy P1 cmp #34 beq lc sta (P2),y iny cpy #17 bcc lb lc lda #"," sta (P2),y iny ld sty P1 jsr IECIN jsr BSOUT ldy P1 cmp #" " beq ld sta P1+1 sta (P2),y iny lda #0 sta (P2),y /* lda #TC_CR jsr BSOUT lda P2+1 ldx P2 jsr INTOUT lda #":" jsr BSOUT lda P2 ldy P2+1 jsr Txtout */ lf tax jsr IECIN jsr BSOUT cmp #" " bne lf cpx #"<" beq lg lda #" " jsr BSOUT lg lda #" " jsr BSOUT lda P1+1 jsr testkeys lh jsr IECIN cmp #0 bne lh beq l2 l3 jsr IECIN ldx STATUS bne l4 tax beq l2 jsr BSOUT jmp l3 l2 lda #TC_CR jsr BSOUT jsr GET beq l5 jsr waitkey l5 ldy #2 beq l4 jmp l0 l4 jsr CLSFIL jmp waitkey .) testkeys .( cmp #"P" beq ok cmp #"S" beq ok rts ok Tout(t1) jsr waitkey cmp #"J" beq ja Tout(tno) rts ja Tout(tok) inc anzfiles rts t1 .asc TC_REV,"YES/NO ",TC_CRL,TC_CRL,TC_CRL .asc TC_CRL,TC_CRL,TC_CRL,TC_CRL,0 &tno .asc TC_REO,"NO ",0 &tok .asc TC_REO,"YES ",0 .) setfadr .( ldx #0 stx INT+1 asl rol INT+1 asl rol INT+1 sta INT ldx INT+1 asl rol INT+1 asl rol INT+1 clc adc INT sta INT txa adc INT+1 sta INT+1 lda #filetab adc INT+1 sta INT+1 tax pla rts .) dir .( lda #TC_FF jsr BSOUT jsr setdirnam jsr SENDNAM lda DEVADR jsr TALK lda SECADR jsr SECTALK lda #0 sta STATUS ldy #3 l0 sty P1 l1 jsr IECIN sta P1+1 ldy STATUS bne l4 jsr IECIN dec P1 bne l1 ldx P1+1 jsr INTOUT lda #" " jsr BSOUT l3 jsr IECIN ldx STATUS bne l4 tax beq l2 jsr BSOUT jmp l3 l2 lda #TC_CR jsr BSOUT jsr GET beq l5 jsr waitkey l5 ldy #2 bne l0 l4 jsr CLSFIL jmp waitkey .) waitkey jsr GET beq waitkey rts setdirnam .( p1 =INT lda #"$" sta INBUF ldx #1 stx p1 ldy #0 l1 lda quellpfad,y beq nodp cmp #":" beq dp iny cpy #PFADLEN bcc l1 nodp lda #":" sta INBUF,x inx dp ldy #0 dp1 lda quellpfad,y sta INBUF,x beq end cmp #":" beq l2a cmp #"/" bne l2 l2a stx p1 l2 inx iny cpy #PFADLEN bcc dp1 end ldx p1 inx lda #"*" sta INBUF,x inx lda #"." sta INBUF,x inx lda #"*" sta INBUF,x inx txa ldx #INBUF jsr SETFNPAR lda #1 ldx quelldrv ldy #0 jmp SETFPAR .) qdrv .( inc quelldrv lda quelldrv cmp #12 bcc ok lda #8 sta quelldrv ok rts .) zdrv .( inc zieldrv lda zieldrv cmp #12 bcc ok lda #8 sta zieldrv ok rts .) quelle .( Tout(quelltxt) jsr LINEIN ldy #0 q1 lda INBUF,y sta quellpfad,y beq end iny cpy #PFADLEN-1 bcc q1 lda #0 sta quellpfad,y end rts quelltxt .asc TC_CR,"PLEASE INPUT NEW SOURCEPATH/ARCHIVE:",TC_CR,0 .) ziel .( Tout(quelltxt) jsr LINEIN ldy #0 q1 lda INBUF,y sta zielpfad,y beq end iny cpy #PFADLEN-1 bcc q1 lda #0 sta zielpfad,y end rts quelltxt .asc TC_CR,"PLEASE INPUT NEW TARGETPATH/ARCHIVE:",TC_CR,0 .) switch .( lda quelldrv ldx zieldrv stx quelldrv sta zieldrv ldx #0 l1 lda quellpfad,x pha lda zielpfad,x sta quellpfad,x pla sta zielpfad,x inx cpx #PFADLEN bcc l1 rts .) inipar .( lda #0 sta quellpfad sta zielpfad lda DEVADR cmp #8 bcc noval cmp #12 bcc ok noval lda #8 ok sta quelldrv sta zieldrv rts .) Txtout .( p =$22 sta p sty p+1 l1 ldy #0 lda (p),y beq le jsr BSOUT inc p bne l1 inc p+1 bne l1 le rts .) iniscreen .( lda #COL_SCHWARZ sta VIC+VIC_EXTCOL sta VIC+VIC_BCKCOL0 lda #TC_HELLGRUEN jsr BSOUT rts .) sysmem =* quelldrv =sysmem zieldrv =sysmem+1 -sysmem +=2 quellpfad =sysmem zielpfad =sysmem+PFADLEN -sysmem +=2*PFADLEN anzfiles =sysmem -sysmem +=1 wi =sysmem wo =sysmem+1 -sysmem +=2 wb =sysmem -sysmem +=256 wxbyt =sysmem wxanz =sysmem+1 -sysmem +=2 ri =sysmem ro =sysmem+1 rf =sysmem+2 -sysmem +=3 rb =sysmem -sysmem +=256 wcnt =sysmem -sysmem +=2 rcnt =sysmem -sysmem +=2 ecnt =sysmem -sysmem +=2 filetab =sysmem ende .) xa-2.3.8/tests/cpktest/pack_ger.a650000600000031500000010000004721012447654537016372 0ustar spectrestaff #include "c64def.def" #define Tout(a) .(:lda #a:jsr Txtout:.) #define Aout(a) .(:lda #b:jsr Txtout:jmp c:b .byt a,0:c .) #define Ibout(a) .(:ldx a:lda #0:jsr INTOUT:.) #define Iout(a) .(:ldx a:lda a+1:jsr INTOUT:.) #define PFADLEN 40 #define FN_WR 3 #define FN_RD 4 #define XCODE $f7 #define Version 1 .( .word $0801 *=$0801 .word basicend,10 .byt $9e,"2064",0 ;sys $0810 basicend .word 0 .byt 0,0,0 .( jsr CLRCH jsr iniscreen jsr inipar menu1 Tout(m1atxt) Tout(quellpfad) Tout(m1btxt) Ibout(quelldrv) Tout(m1ctxt) Tout(zielpfad) Tout(m1dtxt) Ibout(zieldrv) Tout(m1etxt) next jsr GET beq next ldx #0 l1 cmp befkeys,x beq exe inx cpx #Anzbefs bcc l1 bcs next exe jsr exec jmp menu1 exec txa asl tax lda madr+1,x pha lda madr,x pha rts madr .word pack-1,unpack-1,quelle-1,ziel-1,switch-1,dir-1,qdrv-1,zdrv-1 befkeys .asc TC_F1,TC_F2,TC_F3,TC_F5,TC_F8,TC_F7,TC_F4,TC_F6 Anzbefs =8 m1atxt .asc TC_LCH,TC_SCO,TC_FF,TC_LF,TC_LF .asc "(F1) PROGRAMME ZUSAMMENPACKEN",TC_CR,TC_LF .asc "(F2) ARCHIV AUSPACKEN",TC_CR,TC_LF .asc "(F3) QUELLPFAD:",0 m1btxt .asc TC_CR,TC_LF .asc "(F4) QUELLDEVICE:",0 m1ctxt .asc TC_CR,TC_LF .asc "(F5) ZIELPFAD :",0 m1dtxt .asc TC_CR,TC_LF .asc "(F6) ZIELDEVICE :",0 m1etxt .asc TC_CR,TC_LF .asc "(F7) QUELLDIRECTORY",TC_CR,TC_LF .asc "(F8) QUELLE UND ZIEL TAUSCHEN",TC_CR,TC_LF .asc "IHRE EINGABE BITTE",TC_CR,0 .) unpack .( jsr openarcrd bcs cls lda #0 sta rcnt sta rcnt+1 jsr rbyte cmp #Version bne verr loop jsr unpackfile bcc loop Tout(t1) lda rcnt+1 ldx rcnt jsr INTOUT lda #TC_CR jsr BSOUT jsr waitkey cls lda #FN_RD jsr CLOSE rts verr Tout(verrtxt) jmp cls verrtxt .asc "UNGUELTIGE ARCHIV-VERSION",0 t1 .asc "ARCHIV HATTE BYTES #",0 .) unpackfile .( lda #0 sta wcnt sta wcnt+1 lda #TC_CR jsr BSOUT ldy #0 sty P1 l1 jsr rbyte bcs endx ldy P1 sta filetab,y inc P1 cmp #0 beq endnam jsr BSOUT jmp l1 endnam Tout(ask) jsr waitkey cmp #"J" bne nounpack Tout(tok) lda #<-1 sta P1+1 jsr fxopen jsr Getzst bcs xa bcc lo endx jmp end nounpack Tout(tno) xa lda #0 sta P1+1 lo jsr rbyte bcs cls cmp #XCODE bne xb jsr rbyte sta wxanz cmp #0 clc beq cls jsr rbyte sta wxbyt bit P1+1 bpl lo ly lda wxbyt jsr wbyte dec wxanz bne ly jmp lo xb bit P1+1 bpl lo jsr wbyte jmp lo cls php jsr wbuf lda #FN_WR jsr CLOSE Tout(t1) lda wcnt+1 ldx wcnt jsr INTOUT lda #TC_CR jsr BSOUT plp end rts ask .asc TC_CR,"DATEI AUSPACKEN (J/N)?",0 t1 .asc "ERGIBT BYTES #",0 .) incwcnt .( inc wcnt bne l1 inc wcnt+1 l1 rts .) fxopen .( ldy #0 sty INT l1 lda zielpfad,y sta INBUF,y beq l2 iny cmp #":" beq l1a cmp #"/" bne l1b l1a sty INT l1b cpy #PFADLEN bcc l1 l2 ldx INT ldy #0 l3 lda filetab,y sta INBUF,x inx iny cmp #0 bne l3 dex txa ldx #INBUF jsr SETFNPAR lda #FN_WR ldx zieldrv ldy #1 jsr SETFPAR jsr OPEN bcs err jsr clrwrbuf clc err rts .) openarcrd .( ldy #0 l0 lda quellpfad,y beq l1 iny cpy #PFADLEN bcc l0 l1 cpy #0 beq err tya ldx #quellpfad jsr SETFNPAR lda #FN_RD ldx quelldrv ldy #0 jsr SETFPAR jsr OPEN bcs err jsr Getqst bcs err jsr clrrdbuf clc rts err sec rts .) pack .( jsr getlist lda anzfiles beq end jsr openarcwr bcs cls lda #Version jsr wbyte lda #0 sta P1 l1 jsr setfadr sta P2 stx P2+1 jsr packfile inc P1 lda P1 cmp anzfiles bcc l1 jsr wbuf cls lda #FN_WR jsr CLOSE jsr Getzst end jmp LINEIN:rts .) packfile .( Tout(lft) ldy #0 l1 sty P1+1 lda (P2),y jsr BSOUT jsr wbyte ldy P1+1 iny cmp #0 bne l1 jsr fopen bcs le jsr clrwxbyt l2 jsr rbyte bcs l3 jsr wxbyte jmp l2 l3 jsr savwxbyt le lda #FN_RD jsr CLOSE lda #XCODE jsr wbyte lda #0 jsr wbyte lda #TC_CR jsr BSOUT rts lft .asc TC_CR,"cOPYING ",0 .) fopen .( ldy #0 sty INT l1 lda quellpfad,y sta INBUF,y beq l2 iny cmp #":" beq l1a cmp #"/" bne l1b l1a sty INT l1b cpy #PFADLEN bcc l1 l2 ldx INT ldy #0 l3 lda (P2),y sta INBUF,x inx iny cmp #0 bne l3 dex txa ldx #INBUF jsr SETFNPAR lda #FN_RD ldx quelldrv ldy #0 jsr SETFPAR jsr OPEN bcs err jsr clrrdbuf clc err rts .) incrcnt .( inc rcnt bne l1 inc rcnt+1 l1 rts .) rbyte .( ldy ro cpy ri beq leerbuf lda rb,y inc ro clc rts leerbuf lda rf beq ldbuf sec rts ldbuf lda #0 sta ri sta ro ldx #FN_RD jsr CHKIN lda #0 sta STATUS lok jsr BASIN pha lda STATUS beq l0 lda #"L" jsr BSOUT Ibout($90) lda #TC_CR jsr BSOUT l0 pla jsr incrcnt ldy ri sta rb,y iny sty ri iny ;cpy ro beq le lda STATUS beq lok le lda STATUS sta rf jsr CLRCH jmp rbyte .) clrrdbuf .( lda #0 sta ri sta ro sta rf rts .) wxbyte .( ldx wxanz beq add inx bne ad2 pha jsr savwxbyt pla jmp add ad2 cmp wxbyt beq adx pha jsr savwxbyt pla add sta wxbyt adx inc wxanz rts .) clrwxbyt .( lda #0 sta wxanz rts .) savwxbyt .( lda wxanz beq nosav cmp #4 bcs savs lda wxbyt cmp #XCODE beq savs l1 lda wxbyt jsr wbyte dec wxanz bne l1 rts savs lda #XCODE jsr wbyte lda wxanz jsr wbyte lda wxbyt jsr wbyte lda #0 sta wxanz nosav rts .) openarcwr .( ldy #0 l0 lda zielpfad,y beq l1 iny cpy #PFADLEN bcc l0 l1 cpy #0 beq err tya ldx #zielpfad jsr SETFNPAR lda #FN_WR ldx zieldrv ldy #1 jsr SETFPAR jsr OPEN bcs err lda zieldrv jsr Getzst bcs err jsr clrwrbuf clc rts err sec rts .) clrwrbuf .( lda #0 sta wi sta wo rts .) wbyte .( ldy wi sta wb,y iny sty wi iny cpy wo bne nowr pha jsr wbuf pla nowr rts .) wbuf .( ldx #FN_WR jsr CKOUT ldy wo l1 cpy wi beq end lda wb,y jsr BSOUT lda STATUS beq l0 tya pha lda #"W" jsr $e716 lda $90 ora #$40 jsr $e716 lda #TC_CR jsr $e716 pla tay l0 jsr incwcnt iny jmp l1 end lda #0 sta wi sta wo jsr CLRCH rts .) .( &Getqst lda quelldrv jmp Getst &Getzst lda zieldrv &Getst pha jsr CLRCH lda #TC_CR jsr BSOUT pla jsr TALK lda #15+$60 jsr SECTALK lda #0 sta STATUS jsr IECIN pha jsr BSOUT l1 jsr IECIN cmp #0 beq l2 jsr BSOUT lda STATUS beq l1 l2 jsr UNTALK pla cmp #"0" bne err clc rts err sec rts .) /* showlist .( lda #0 sta P1 l1 lda P1 cmp anzfiles bcs le jsr setfadr lda #TC_CR jsr BSOUT lda INT ldy INT+1 jsr Txtout inc P1 jmp l1 le rts .) */ .( l4x jmp l4 &getlist lda #0 sta anzfiles lda #TC_FF jsr BSOUT jsr setdirnam jsr SENDNAM lda DEVADR jsr TALK lda SECADR jsr SECTALK lda #0 sta STATUS ldy #3 l0 sty P1 l1 jsr IECIN sta P1+1 ldy STATUS bne l4x jsr IECIN dec P1 bne l1 ldx P1+1 jsr INTOUT lda #" " jsr BSOUT la jsr IECIN cmp #0 beq l4x cmp #TC_REV bne l3x jmp l3 l3x jsr BSOUT cmp #34 bne la lda anzfiles jsr setfadr sta P2 stx P2+1 ldy #0 lb sty P1 jsr IECIN jsr BSOUT ldy P1 cmp #34 beq lc sta (P2),y iny cpy #17 bcc lb lc lda #"," sta (P2),y iny ld sty P1 jsr IECIN jsr BSOUT ldy P1 cmp #" " beq ld sta P1+1 sta (P2),y iny lda #0 sta (P2),y /* lda #TC_CR jsr BSOUT lda P2+1 ldx P2 jsr INTOUT lda #":" jsr BSOUT lda P2 ldy P2+1 jsr Txtout */ lf tax jsr IECIN jsr BSOUT cmp #" " bne lf cpx #"<" beq lg lda #" " jsr BSOUT lg lda #" " jsr BSOUT lda P1+1 jsr testkeys lh jsr IECIN cmp #0 bne lh beq l2 l3 jsr IECIN ldx STATUS bne l4 tax beq l2 jsr BSOUT jmp l3 l2 lda #TC_CR jsr BSOUT jsr GET beq l5 jsr waitkey l5 ldy #2 beq l4 jmp l0 l4 jsr CLSFIL jmp waitkey .) testkeys .( cmp #"P" beq ok cmp #"S" beq ok rts ok Tout(t1) jsr waitkey cmp #"J" beq ja Tout(tno) rts ja Tout(tok) inc anzfiles rts t1 .asc TC_REV,"JA/NEIN",TC_CRL,TC_CRL,TC_CRL .asc TC_CRL,TC_CRL,TC_CRL,TC_CRL,0 &tno .asc TC_REO,"NEIN ",0 &tok .asc TC_REO,"JA ",0 .) setfadr .( ldx #0 stx INT+1 asl rol INT+1 asl rol INT+1 sta INT ldx INT+1 asl rol INT+1 asl rol INT+1 clc adc INT sta INT txa adc INT+1 sta INT+1 lda #filetab adc INT+1 sta INT+1 tax pla rts .) dir .( lda #TC_FF jsr BSOUT jsr setdirnam jsr SENDNAM lda DEVADR jsr TALK lda SECADR jsr SECTALK lda #0 sta STATUS ldy #3 l0 sty P1 l1 jsr IECIN sta P1+1 ldy STATUS bne l4 jsr IECIN dec P1 bne l1 ldx P1+1 jsr INTOUT lda #" " jsr BSOUT l3 jsr IECIN ldx STATUS bne l4 tax beq l2 jsr BSOUT jmp l3 l2 lda #TC_CR jsr BSOUT jsr GET beq l5 jsr waitkey l5 ldy #2 bne l0 l4 jsr CLSFIL jmp waitkey .) waitkey jsr GET beq waitkey rts setdirnam .( p1 =INT lda #"$" sta INBUF ldx #1 stx p1 ldy #0 l1 lda quellpfad,y beq nodp cmp #":" beq dp iny cpy #PFADLEN bcc l1 nodp lda #":" sta INBUF,x inx dp ldy #0 dp1 lda quellpfad,y sta INBUF,x beq end cmp #":" beq l2a cmp #"/" bne l2 l2a stx p1 l2 inx iny cpy #PFADLEN bcc dp1 end ldx p1 inx lda #"*" sta INBUF,x inx lda #"." sta INBUF,x inx lda #"*" sta INBUF,x inx txa ldx #INBUF jsr SETFNPAR lda #1 ldx quelldrv ldy #0 jmp SETFPAR .) qdrv .( inc quelldrv lda quelldrv cmp #12 bcc ok lda #8 sta quelldrv ok rts .) zdrv .( inc zieldrv lda zieldrv cmp #12 bcc ok lda #8 sta zieldrv ok rts .) quelle .( Tout(quelltxt) jsr LINEIN ldy #0 q1 lda INBUF,y sta quellpfad,y beq end iny cpy #PFADLEN-1 bcc q1 lda #0 sta quellpfad,y end rts quelltxt .asc TC_CR,"BITTE NEUEN QUELLPFAD EINGEBEN:",TC_CR,0 .) ziel .( Tout(quelltxt) jsr LINEIN ldy #0 q1 lda INBUF,y sta zielpfad,y beq end iny cpy #PFADLEN-1 bcc q1 lda #0 sta zielpfad,y end rts quelltxt .asc TC_CR,"BITTE NEUEN ZIELPFAD EINGEBEN:",TC_CR,0 .) switch .( lda quelldrv ldx zieldrv stx quelldrv sta zieldrv ldx #0 l1 lda quellpfad,x pha lda zielpfad,x sta quellpfad,x pla sta zielpfad,x inx cpx #PFADLEN bcc l1 rts .) inipar .( lda #0 sta quellpfad sta zielpfad lda DEVADR cmp #8 bcc noval cmp #12 bcc ok noval lda #8 ok sta quelldrv sta zieldrv rts .) Txtout .( p =$22 sta p sty p+1 l1 ldy #0 lda (p),y beq le jsr BSOUT inc p bne l1 inc p+1 bne l1 le rts .) iniscreen .( lda #COL_SCHWARZ sta VIC+VIC_EXTCOL sta VIC+VIC_BCKCOL0 lda #TC_HELLGRUEN jsr BSOUT rts .) sysmem =* quelldrv =sysmem zieldrv =sysmem+1 -sysmem +=2 quellpfad =sysmem zielpfad =sysmem+PFADLEN -sysmem +=2*PFADLEN anzfiles =sysmem -sysmem +=1 wi =sysmem wo =sysmem+1 -sysmem +=2 wb =sysmem -sysmem +=256 wxbyt =sysmem wxanz =sysmem+1 -sysmem +=2 ri =sysmem ro =sysmem+1 rf =sysmem+2 -sysmem +=3 rb =sysmem -sysmem +=256 wcnt =sysmem -sysmem +=2 rcnt =sysmem -sysmem +=2 ecnt =sysmem -sysmem +=2 filetab =sysmem ende .) xa-2.3.8/tests/cpp/0000755000031500000010000000000013125354743013401 5ustar spectrestaffxa-2.3.8/tests/cpp/Makefile0000644000031500000010000000017512004304550015026 0ustar spectrestaffdefault: $(CC) -E over.c > over.asm ../../xa -w over.asm ../hextool -cmp=expected.o < a.o65 clean: rm -f over.asm a.o65 xa-2.3.8/tests/cpp/expected.o0000644000031500000010000000002212004304505015336 0ustar spectrestaff©L`©Ðù`¯ÀÀÀxa-2.3.8/tests/cpp/over.c0000644000031500000010000000046212004304401014477 0ustar spectrestaff/* #define BUG */ #ifdef BUG #define WW AA #define AA WW #else #define CC 1 #define WW CC #define AA WW #endif /* This has a .c extension for those cc -E's that won't deal with .asm */ * = $0000 lda #AA jmp buggy rts #include "over.h" /* the buggy will force a line number to be printed */ buggy xa-2.3.8/tests/cpp/over.h0000644000031500000010000000011710552224700014512 0ustar spectrestaff #define X W #define W 5 fuzz lda #W sta $0400 bne fuzz rts lda @$c0c0c0 xa-2.3.8/tests/dos51/0000755000031500000010000000000013125354743013552 5ustar spectrestaffxa-2.3.8/tests/dos51/Makefile0000644000031500000010000000041212447654160015211 0ustar spectrestaffdefault: # xa should not allow this to happen. if it does, this test is no good. ../../xa -DBUG test.s || exit 0 && exit 1 # expected-to-fail tests did fail. should be no more errors now. ../../xa test.s -o test.o ../hextool -cmp=ok < test.o clean: rm -f *.o xa-2.3.8/tests/dos51/dos51.inc0000644000031500000010000000465212447651260015207 0ustar spectrestaff/* dos wedge code for inlining into routines */ /* define SA51 to allow stand-alone generation */ #ifdef SA51 .word SA51 * = SA51 #endif /* otherwise assume this has been inlined via #include <> */ /* define BASIC51 to use BASIC interface stub */ #ifdef BASIC51 jsr $aefd jsr $ad9e jsr $b6a3 ; leaving a=len x=lb y=hb #endif /* otherwise load a with length, x/y = lb/hb */ .( crunchsrv = $a57c setlfs = $ffba setnam = $ffbd open = $ffc0 close = $ffc3 clall = $ffe7 chkin = $ffc6 chkout = $ffc9 clrchn = $ffcc chrin = $ffcf getin = $ffe4 print = $ffd2 readst = $ffb7 chrout = print ready = $e37b cnvrtdec = $bdcd erasealine = 59903 workzp = $a5 sta work1 sty workzp+1 stx workzp ; set the filename (directory, error channel and commands) ; a, x and y already setup for us jsr setnam ; are we requesting just the error channel? ldx work1 beq errchn ; yes ; are we requesting a disk directory? ldy #0 lda (workzp),y cmp #"$" bne errchn ; no ; yes, display directory lda #$01 ldx 186 ldy #$00 jsr setlfs jsr open ; open 1,dev,0 to read as BASIC formatted text lda #147 jsr print clc ldx #01 jsr chkin bcs dirdone jsr chrin jsr chrin lda #$0d jsr print ; routine to print each line of the directory dirpll jsr chrin jsr chrin ; skip line link jsr chrin ; grab length (as line #) sta work1 jsr chrin sta work2 ; stash for later jsr readst ; EOF or other error? bne dirdone ; yes, end directory lda work2 ; no, print this line ldx work1 jsr cnvrtdec ; first the number/length lda #$20 jsr print ; and a space jsr chrin dirpl jsr print ; then the filename in quotes and filetype until a null jsr chrin adc #0 bne dirpl ; no null yet lda #13 ; yes, null, print CR jsr print jmp dirpll ; and do next line ; finish directory and clear channel, then fall through to errchn dirdone lda #1 jsr close jsr clall lda #0 jsr setnam ; common routine for error channel and disk commands errchn lda #15 ldx $ba ldy #15 jsr setlfs ; open 15,8,15,command jsr open lda #18 jsr print ; rvson ; read until there's a null, adding $0d for devices that don't errchnl ldx #15 jsr chkin jsr chrin sta work1 jsr readst ; power 64 sucks sometimes =-( sta work2 ; its emulated messages have no $0d lda work1 jsr print lda work2 beq errchnl lda work1 cmp #13 beq errchnd lda #13 jsr print errchnd lda #15 jsr close jsr clall lda #146 jsr print ; rvsoff rts work1 .byt 0 work2 .byt 0 .) xa-2.3.8/tests/dos51/ok0000644000031500000010000000031512447651423014106 0ustar spectrestaff#ÁìÁ„¦†¥ ½ÿ®ìÁðs ±¥É$Ðk©¦º  ºÿ Àÿ©“ Òÿ¢ Æÿ°E Ïÿ Ïÿ© Òÿ Ïÿ Ïÿ ÏÿìÁ ÏÿíÁ ·ÿÐ#­íÁ®ìÁ ͽ© Òÿ Ïÿ Òÿ ÏÿiÐö© ÒÿL^Á© Ãÿ çÿ© ½ÿ©¦º  ºÿ Àÿ© Òÿ¢ Æÿ ÏÿìÁ ·ÿíÁ­ìÁ Òÿ­íÁðä­ìÁÉ ð© Òÿ© Ãÿ çÿ©’ Òÿ`xa-2.3.8/tests/dos51/test.s0000644000031500000010000000011112447654114014707 0ustar spectrestaff#define SA51 $c123 #include "dos51.inc" #ifdef BUG jsr crunchsrv #endif xa-2.3.8/tests/fordef/0000755000031500000010000000000013125354743014064 5ustar spectrestaffxa-2.3.8/tests/fordef/Makefile0000644000031500000010000000046112004345161015512 0ustar spectrestaffdefault: # this must not pass. ../../xa -DFAIL test3.asm || exit 0 && exit 1 # these must pass. ../../xa test3.asm ../hextool -cmp=test3.ok < a.o65 # testing warnings. ../../xa -e test.out test.asm ../hextool -cmp=ok.out < test.out ../hextool -cmp=test1.ok < a.o65 clean: rm -f a.o65 test.out xa-2.3.8/tests/fordef/ok.out0000644000031500000010000000030212447451033015215 0ustar spectrestafftest.asm:line 6: 0400: Warning - Can't optimize forward-defined label; using absolute addressing test.asm:line 7: 0403: Warning - Can't optimize forward-defined label; using absolute addressing xa-2.3.8/tests/fordef/test.asm0000644000031500000010000000033410414661103015532 0ustar spectrestaff .word $0400 * = $0400 /* this should generate optimizer warnings */ lda forward1 sta forward2 /* this shouldn't */ jmp forward3 /* and this won't */ t1 lda `forward1 sta `forward2 rts #include "test2.asm" xa-2.3.8/tests/fordef/test1.ok0000644000031500000010000000002112004345005015432 0ustar spectrestaff­L¥…``xa-2.3.8/tests/fordef/test2.asm0000644000031500000010000000005510414652100015611 0ustar spectrestaff forward1 = $02 forward2 = $03 forward3 rts xa-2.3.8/tests/fordef/test3.asm0000644000031500000010000000052610417073232015623 0ustar spectrestaff .word $0400 *=$0400 /* define this if you want to crash and burn */ #ifdef FAIL jmp `forward3 bne `forward3 lda (`forward1),y lda (`forward3),y #echo congrats, you have FAILED! #endif sta `forward3 /* this looks like it should fail, but won't because there is no ambiguity */ lda (forward1),y jmp forward3 #include "test2.asm" xa-2.3.8/tests/fordef/test3.ok0000644000031500000010000000001312004344677015453 0ustar spectrestaff±L`xa-2.3.8/tests/harness0000755000031500000010000000266112004347473014212 0ustar spectrestaff#!/usr/bin/perl -s $make ||= "make"; $cc ||= "cc"; $cflags ||= ''; $ENV{'MAKE'} = $make; $ENV{'CC'} = $cc; $ENV{'CFLAGS'} = $cflags; $|++; $dtests = $tests || "ALL"; print <<"EOF"; CC = $cc CFLAGS = $cflags MAKE = $make tests to run: $dtests EOF # Get a list of all directories. If there is a Makefile there, do it. # If there is not, see if there is an .s file and an ok binary to cmp to. # Otherwise, do nothing (acknowledge and ignore directories we don't grok). opendir(D, ".") || die("test harness failed: $!\n"); W: while($x = readdir(D)) { next W if ($x =~ /^\./); next W if (length($tests) && ($tests !~ /$x/)); next W if (!chdir($x)); $x = substr($x . " " . ("." x 79), 0, 50); print STDOUT "$x > "; if (-e "Makefile") { print STDOUT "running Makefile\n"; print STDOUT "=" x 79, "\n"; system("$make clean"); print STDOUT "-" x 79, "\n"; system("$make"); print STDOUT "-" x 79, "\n"; if ($?) { print STDOUT "## FAILURE (make clean NOT run) ##\n"; exit 1; } system("$make clean"); print STDOUT "=" x 35, " PASSED! ", "=" x 35, "\n"; } elsif (-e "ok" && -e "test.s") { unlink("a.o65"); &failed("../../xa test.s"); &failed("../hextool -cmp=ok < a.o65"); unlink("a.o65"); print STDOUT "PASSED\n"; } else { print STDOUT "ignored\n"; } chdir(".."); } closedir(D); print STDOUT "\n## ALL TESTS PASS ##\n"; exit 0; sub failed { system(@_); if ($?) { print STDOUT "## FAILURE ##\n"; exit 1; } } xa-2.3.8/tests/hextool0000755000031500000010000000234312004341236014215 0ustar spectrestaff#!/usr/bin/perl -s # This tool either emits hex in a machine or human parseable format, or # compares two binaries in the form of cmp. It is mostly to deal with # systems with an unreliable hexdump, that *lack* hexdump (or od), and/or # emit non-standard output. # "use bytes" BEGIN { $^H |= 0x00000008 unless ($] < 5.006); } if ($output || $noutput) { # check output mode. If $output, there must be output. If there is # $noutput there must NOT be output. Feed tee or something to this. $wasoutput = 0; while(<>) { $wasoutput++; } exit (($wasoutput && $output) ? 0 : ($wasoutput && $noutput) ? 1 : (!$wasoutput && !$noutput) ? 0 : 1); } if ($cmp) { # compare mode. both files must fit in memory. to eliminate any # weirdness about endianness, encoding, etc., we unpack them to # hex bytes and just compare strings. undef $/; open(W, "$cmp") || die("can't open $cmp: $!\n"); $cmp = unpack("H*", ); close(W); $std = unpack("H*", <>); if ($cmp ne $std) { print <<"EOF"; FAILED! received from stdin ------------------- $std expected to equal ----------------- $cmp FAILED! EOF exit 255; } exit 0; } # hexdump mode. accept data on stdin, spew a stream of hex bytes. while(<>) { print STDOUT unpack("H*", $_); } xa-2.3.8/tests/incerr/0000755000031500000010000000000013125354743014101 5ustar spectrestaffxa-2.3.8/tests/incerr/Makefile0000644000031500000010000000022612004345467015537 0ustar spectrestaffdefault: # in 6502 mode, it will fail. ../../xa test.s || exit 0 && exit 1 # in 65816 mode, it will pass. ../../xa -w test.s clean: rm -f a.o65 xa-2.3.8/tests/incerr/test.65020000644000031500000010000000000510560141672015364 0ustar spectrestaff .xl xa-2.3.8/tests/incerr/test.s0000644000031500000010000000002510560141751015232 0ustar spectrestaff#include "test.6502" xa-2.3.8/tests/ldoreloc/0000755000031500000010000000000013125354743014422 5ustar spectrestaffxa-2.3.8/tests/ldoreloc/1.s0000644000031500000010000000003010546755151014741 0ustar spectrestaffjsr bla: loop: jmp loop xa-2.3.8/tests/ldoreloc/2.s0000644000031500000010000000001110546755151014741 0ustar spectrestaffbla: rts xa-2.3.8/tests/ldoreloc/Makefile0000644000031500000010000000062512004302272016046 0ustar spectrestaff default: all all: t 1.o65: 1.s ../../xa -R -c -o 1.o65 1.s ../hextool 1.o65 > 1.o65.hex 2.o65: 2.s ../../xa -R -c -o 2.o65 2.s ../hextool 2.o65 > 2.o65.hex linked.o65: 1.o65 2.o65 ../../ldo65 -o linked.o65 1.o65 2.o65 ../hextool linked.o65 > linked.o65.hex t: linked.o65 ../../reloc65 -bt 32768 -xt -o t linked.o65 ../hextool t > t.hex ../hextool -cmp=t < t.ok clean: rm -f *.o65 *.hex t xa-2.3.8/tests/ldoreloc/t.ok0000644000031500000010000000000710546755151015217 0ustar spectrestaff €L€`xa-2.3.8/tests/ldoreloc/xatestanalysis.txt0000644000031500000010000000664210546755151020251 0ustar spectrestaff mkdir xatest cd xatest echo "jsr bla: loop: jmp loop" > 1.s echo "bla: rts" > 2.s xa -R -c -o 1.o65 1.s xa -R -c -o 2.o65 2.s ldo65 -o linked.o65 1.o65 2.o65 reloc65 -bt 32768 -xt -o t linked.o65 hexdump -C t output: 00000000 20 06 80 4c 03 8c 60 | ..L..`| 00000007 The bytes 20 06 80 are correct, it's JSR $8006. But 4c 03 8c means JMP $8c03. What's wrong here? Do I use it in a wrong way? Following procedure leads to the expected code: echo "jsr bla: loop: jmp loop: bla: rts" > 1.s xa -R -c -o 1.o65 1.s ldo65 -o linked.o65 1.o65 reloc65 -bt 32768 -xt -o t linked.o65 hexdump -C t I use 2.3.0, it comes with Debian Testing. ============================================================================== Analysis: cat 1.o65.hex 00000000 01 00 6f 36 35 00 00 10 00 10 06 00 00 04 00 00 |..o65...........| 00000010 00 40 00 00 04 00 00 00 00 00 00 20 00 00 4c 03 |.@......... ..L.| 00000020 10 01 00 62 6c 61 00 02 80 00 00 03 82 00 00 01 |...bla..........| 00000030 00 6c 6f 6f 70 00 02 03 10 |.loop....| 00000039 file65 -V 1.o65 1.o65: o65 version 0 object file mode: 1000 =[object][16bit][byte relocation][CPU 6502][align 1] text segment @ $1000 - $1006 [$0006 bytes] data segment @ $0400 - $0400 [$0000 bytes] bss segment @ $4000 - $4000 [$0000 bytes] zero segment @ $0004 - $0004 [$0000 bytes] stack size $0000 bytes (i.e. unknown) Undefined Labels: 1 bla Global Labels: 1 loop (segID=2 (text), offset=1003) ==> text segment start $1000, loop is at $1003 -> ok undef'd label bla stored as zero (00 00) in opcode -> ok relocation table entry: $1001, ADR, undef'd, label #0 -> ok $1004, ADR, text segment -> ok --------------------------------------------------- cat 2.o65.hex 00000000 01 00 6f 36 35 00 00 10 00 10 01 00 00 04 00 00 |..o65...........| 00000010 00 40 00 00 04 00 00 00 00 00 00 60 00 00 00 00 |.@.........`....| 00000020 01 00 62 6c 61 00 02 00 10 |..bla....| file65 -V 2.o65 2.o65: o65 version 0 object file mode: 1000 =[object][16bit][byte relocation][CPU 6502][align 1] text segment @ $1000 - $1001 [$0001 bytes] data segment @ $0400 - $0400 [$0000 bytes] bss segment @ $4000 - $4000 [$0000 bytes] zero segment @ $0004 - $0004 [$0000 bytes] stack size $0000 bytes (i.e. unknown) Undefined Labels: 0 Global Labels: 1 bla (segID=2 (text), offset=1000) => text segment start $1000 -> ok no relocation table entries -> ok global label text segment, at $1000 -> ok --------------------------------------------------- ldo65 -o linked.o65 1.o65 2.o65 linked.o65.hex 00000000 01 00 6f 36 35 00 00 00 00 04 07 00 00 10 00 00 |..o65...........| 00000010 00 40 00 00 02 00 00 00 00 00 00 20 06 04 4c 03 |.@......... ..L.| 00000020 10 60 00 00 02 82 03 82 00 00 02 00 6c 6f 6f 70 |.`..........loop| 00000030 00 02 03 04 62 6c 61 00 02 06 04 |....bla....| ile65 -V linked.o65 linked.o65: o65 version 0 executable file mode: 0000 =[executable][16bit][byte relocation][CPU 6502][align 1] text segment @ $0400 - $0407 [$0007 bytes] data segment @ $1000 - $1000 [$0000 bytes] bss segment @ $4000 - $4000 [$0000 bytes] zero segment @ $0002 - $0002 [$0000 bytes] stack size $0000 bytes (i.e. unknown) Undefined Labels: 0 Global Labels: 2 loop (segID=2 (text), offset=0403) bla (segID=2 (text), offset=0406) => text segment start $0400 $0400 jsr $0406 -> RTS -> ok $0403 jmp $1003 >>>>>>>>>>>>>>>> wrong !!! should be $0403 xa-2.3.8/tests/masmcom/0000755000031500000010000000000013125354743014253 5ustar spectrestaffxa-2.3.8/tests/masmcom/Makefile0000644000031500000010000000031213125354052015700 0ustar spectrestaffdefault: # compile with masm mode on. ../../xa -M -o test.o test.s ../hextool -cmp=okmasm < test.o # compile without ../../xa -o test.o test.s ../hextool -cmp=oknomasm < test.o clean: rm -f *.o xa-2.3.8/tests/masmcom/okmasm0000644000031500000010000000000213125354113015444 0ustar spectrestaff©xa-2.3.8/tests/masmcom/oknomasm0000644000031500000010000000000613125354213016006 0ustar spectrestaff©©©:xa-2.3.8/tests/masmcom/test.s0000644000031500000010000000016613125354212015410 0ustar spectrestaff/* when assembled with/without -M, we get two different objects */ lda #00 ; and this: lda #01 ; is why : lda #":" xa-2.3.8/tests/mvnmvp/0000755000031500000010000000000013125354743014142 5ustar spectrestaffxa-2.3.8/tests/mvnmvp/Makefile0000644000031500000010000000040712447627017015606 0ustar spectrestaffdefault: # xa should not allow this to happen. if it does, this test is no good. ../../xa test.s || exit 0 && exit 1 # expected-to-fail tests did fail. should be no more errors now. ../../xa -w test.s -o test.o ../hextool -cmp=ok < test.o clean: rm -f *.o xa-2.3.8/tests/mvnmvp/ok0000644000031500000010000000003312447627357014504 0ustar spectrestaff­ ÐJTTTfDDDˆêZ¶Z¶xa-2.3.8/tests/mvnmvp/test.s0000644000031500000010000000034212447627330015305 0ustar spectrestaff; test instructions that failed during our testing ; and test instructions in the tokenizer bordering mvn/mvp w = $01 lda $d020 lsr mvn w, $02 mvn $0201 mvn $0066 mvp $03, w+3 mvp $0403 mvp $0088 nop .byt $5a, $b6 .word $b65a xa-2.3.8/tests/nonl/0000755000031500000010000000000013125354743013565 5ustar spectrestaffxa-2.3.8/tests/nonl/ok0000644000031500000010000000000612004345551014105 0ustar spectrestaff©`xa-2.3.8/tests/nonl/test.s0000644000031500000010000000003010413355204014707 0ustar spectrestaff lda #4 sta !$0005 rtsxa-2.3.8/tests/nonl/test2.asm0000644000031500000010000000002310413353404015311 0ustar spectrestaff#include "test.asm"xa-2.3.8/tests/op816/0000755000031500000010000000000013125354744013475 5ustar spectrestaffxa-2.3.8/tests/op816/Makefile0000644000031500000010000000040712450033510015117 0ustar spectrestaffdefault: # xa should not allow this to happen. if it does, this test is no good. ../../xa test.s || exit 0 && exit 1 # expected-to-fail tests did fail. should be no more errors now. ../../xa -w test.s -o test.o ../hextool -cmp=ok < test.o clean: rm -f *.o xa-2.3.8/tests/op816/ok0000644000031500000010000000113612450033477014027 0ustar spectrestaff [ [[[ÿL$[[[[[ÿLJ ]!"[ÿ#$%&'()"*+,[-[.[/[ÿLr0123456789[:;<[=[>[?[ÿL˜@ABCDDDEFGHIDJKL]M[N[O[ÿL¼PQRSTUUUVWXY[Z[\[ÿ][^[_[ÿLä`abqcdefghifjkl[m[n[o[ÿL pqrstuvwxy[z{|[}[~[[ÿL/€‚%ƒ„…†‡ˆ‰ˆŠ‹Œ[[Ž[[ÿLU‘ ’ “ ” • – — ˜™[š›[ž[Ÿ[ÿLx ª¡ ¢ª£ ¤ ¥ ¦ § ¨©ªª«¬[­[®[¯[ÿL°± ² ³ ´ µ ¶ · ¸¹[º»¼[½[¾[¿[ÿLÃÀÌÁ ÂÌÃ Ä Å Æ Ç ÈÉÌÊËÌ[Í[Î[Ï[ÿLèÐÑ Ò Ó Ô Õ Ö × ØÙ[ÚÛÜ4Ý[Þ[ß[ÿLàîáâîãäåæçèéîêëì[í[î[ï[ÿL3ðñòóôõö÷øù[úûü[ý[þ[ÿ[ÿLZ`4@xa-2.3.8/tests/op816/test.s0000600000031500000010000001500712450031401014611 0ustar spectrestaff; Copyright (c) 2014, Alessandro Gatti - frob.it ; 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. ; ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. #define ZEROPAGE_0 $0 #define ZEROPAGE_1 $1 #define ZEROPAGE_2 $2 #define ZEROPAGE_3 $3 #define ZEROPAGE_4 $4 #define ZEROPAGE_5 $5 #define ZEROPAGE_6 $6 #define ZEROPAGE_7 $7 #define ZEROPAGE_8 $8 #define ZEROPAGE_9 $9 #define ZEROPAGE_A $a #define ZEROPAGE_B $b #define ZEROPAGE_C $c #define ZEROPAGE_D $d #define ZEROPAGE_E $e #define ZEROPAGE_F $f *=$1000 row0 BRK ORA (ZEROPAGE_0,X) COP #$00 ORA ZEROPAGE_0,S TSB ZEROPAGE_0 ORA ZEROPAGE_0 ASL ZEROPAGE_0 ORA [ZEROPAGE_0] PHP ORA #$00 ASL PHD TSB datablockabs ORA datablockabs ASL datablockabs ORA @datablockabs+@$FF0000 JMP row1 row1 BPL row1_target ORA (ZEROPAGE_1),Y row1_target ORA (ZEROPAGE_1) ORA (ZEROPAGE_1,S),Y TRB ZEROPAGE_1 ORA ZEROPAGE_1,X ASL ZEROPAGE_1,X ORA [ZEROPAGE_1],Y CLC ORA datablockabs,Y INC TCS TRB datablockabs ORA datablockabs,X ASL datablockabs,X ORA @datablockabs+@$FF0000,X JMP row2 row2 JSR farcode AND (ZEROPAGE_2,X) JSR @datablockabs+@$FF0000 AND ZEROPAGE_2,S BIT ZEROPAGE_2 AND ZEROPAGE_2 ROL ZEROPAGE_2 AND [ZEROPAGE_2] PLP AND #$22 ROL PLD BIT datablockabs AND datablockabs ROL datablockabs AND @datablockabs+@$FF0000 JMP row3 row3 BMI row3_target AND (ZEROPAGE_3),Y row3_target AND (ZEROPAGE_3) AND (ZEROPAGE_3,S),Y BIT ZEROPAGE_3,X AND ZEROPAGE_3,X ROL ZEROPAGE_3,X AND [ZEROPAGE_3],Y SEC AND datablockabs,Y DEC TSC BIT datablockabs,X AND datablockabs,X ROL datablockabs,X AND @datablockabs+@$FF0000,X JMP row4 row4 RTI EOR (ZEROPAGE_4,X) .byte $42 ; WDM EOR ZEROPAGE_3,S MVP $44,$44 ;$4444 ; Should be $44, $44 instead EOR ZEROPAGE_4 LSR ZEROPAGE_4 EOR [ZEROPAGE_4] PHA EOR #$44 LSR PHK JMP farcode EOR datablockabs LSR datablockabs EOR @datablockabs+@$FF0000 JMP row5 row5 BVC row5_target EOR (ZEROPAGE_5),Y row5_target EOR (ZEROPAGE_5) EOR (ZEROPAGE_5,S),Y MVN $55,$55 ; $5555 ; Should be $55, $55 instead EOR ZEROPAGE_5,X LSR ZEROPAGE_5,X EOR [ZEROPAGE_5],Y CLI EOR datablockabs,Y PHY TCD JMP @datablockabs+@$FF0000 EOR datablockabs,X LSR datablockabs,X EOR @datablockabs+@$FF0000,X JMP row6 row6 RTS ADC (ZEROPAGE_6,X) PER datablockabs ADC ZEROPAGE_6,S STZ ZEROPAGE_6 ADC ZEROPAGE_6 ROR ZEROPAGE_6 ADC [ZEROPAGE_6] PLA ADC #$66 ROR RTL JMP (datablockabs) ADC datablockabs ROR datablockabs ADC @datablockabs+@$FF0000 JMP row7 row7 BVS row7_target ADC (ZEROPAGE_7),Y row7_target ADC (ZEROPAGE_7) ADC (ZEROPAGE_7,S),Y STZ ZEROPAGE_7,X ADC ZEROPAGE_7,X ROR ZEROPAGE_7,X ADC [ZEROPAGE_7],Y SEI ADC datablockabs,Y PLY TDC JMP (datablockabs,X) ADC datablockabs,X ROR datablockabs,X ADC @datablockabs+@$FF0000,X JMP row8 row8 BRA row8_target STA (ZEROPAGE_8,X) row8_target BRL datablockabs STA ZEROPAGE_8,S STY ZEROPAGE_8 STA ZEROPAGE_8 STX ZEROPAGE_8 STA [ZEROPAGE_8] DEY BIT #$88 TXA PHB STY datablockabs STA datablockabs STX datablockabs STA @datablockabs+@$FF0000 JMP row9 row9 BCC row9_target STA (ZEROPAGE_9),Y row9_target STA (ZEROPAGE_9) STA (ZEROPAGE_9,S),Y STY ZEROPAGE_9,X STA ZEROPAGE_9,X STX ZEROPAGE_9,Y STA [ZEROPAGE_9],Y TYA STA datablockabs,Y TXS TXY STA datablockabs,X STZ datablockabs,X STA @datablockabs+@$FF0000,X JMP rowa rowa LDY #$AA LDA (ZEROPAGE_A,X) LDX #$AA LDA ZEROPAGE_A,S LDY ZEROPAGE_A LDA ZEROPAGE_A LDX ZEROPAGE_A LDA [ZEROPAGE_A] TAY LDA #$AA TAX PLB LDY datablockabs LDA datablockabs LDX datablockabs LDA @datablockabs+@$FF0000 JMP rowb rowb BCS rowb_target LDA (ZEROPAGE_B),Y rowb_target LDA (ZEROPAGE_B) LDA (ZEROPAGE_B,S),Y LDY ZEROPAGE_B,X LDA ZEROPAGE_B,X LDX ZEROPAGE_B,Y LDA [ZEROPAGE_B],Y CLV LDA datablockabs,Y TSX TYX LDY datablockabs,X LDA datablockabs,X LDX datablockabs,Y LDA @datablockabs+@$FF0000,X JMP rowc rowc CPY #$CC CMP (ZEROPAGE_C,X) REP #$CC CMP ZEROPAGE_C,S CPY ZEROPAGE_C CMP ZEROPAGE_C DEC ZEROPAGE_C CMP [ZEROPAGE_C] INY CMP #$CC DEX WAI CPY datablockabs CMP datablockabs DEC datablockabs CMP @datablockabs+@$FF0000 JMP rowd rowd BNE rowd_target CMP (ZEROPAGE_D),Y rowd_target CMP (ZEROPAGE_D) CMP (ZEROPAGE_D,S),Y PEI (ZEROPAGE_D) CMP ZEROPAGE_D,X DEC ZEROPAGE_D,X CMP [ZEROPAGE_D],Y CLD CMP datablockabs,Y PHX STP .byte $DC, $34, $12 ; JML (label) CMP datablockabs,X DEC datablockabs,X CMP @datablockabs+@$FF0000,X JMP rowe rowe CPX #$EE SBC (ZEROPAGE_E,X) SEP #$EE SBC ZEROPAGE_E,S CPX ZEROPAGE_E SBC ZEROPAGE_E INC ZEROPAGE_E SBC [ZEROPAGE_E] INX SBC #$EE NOP XBA CPX datablockabs SBC datablockabs INC datablockabs SBC @datablockabs+@$FF0000 JMP rowf rowf BEQ rowf_target SBC (ZEROPAGE_F),Y rowf_target SBC (ZEROPAGE_F) SBC (ZEROPAGE_F,S),Y PEA $1000 SBC ZEROPAGE_F,X INC ZEROPAGE_F,X SBC [ZEROPAGE_F],Y SED SBC datablockabs,Y PLX XCE JSR (datablockabs,X) SBC datablockabs,X INC datablockabs,X SBC @datablockabs+@$FF0000,X JMP end end RTS datablockabs .word $1234 farcode RTI xa-2.3.8/tests/openpp/0000755000031500000010000000000013125354744014121 5ustar spectrestaffxa-2.3.8/tests/openpp/Makefile0000644000031500000010000000050412447653742015566 0ustar spectrestaffdefault: # xa should not allow this to happen. if it does, this test is no good. ../../xa test.inc || exit 0 && exit 1 # expected-to-fail tests did fail. should be no more errors now. ../../xa -DBUG test.s -o test.o ../hextool -cmp=ok < test.o ../../xa test.s -o test.o ../hextool -cmp=ok < test.o clean: rm -f *.o xa-2.3.8/tests/openpp/ok0000644000031500000010000000001412447653263014454 0ustar spectrestaffÀ©] Òÿ©] Òÿxa-2.3.8/tests/openpp/test.inc0000644000031500000010000000003710552227734015572 0ustar spectrestaff#ifdef BUGOUTTTTT /* #endif */ xa-2.3.8/tests/openpp/test.s0000644000031500000010000000044212447653262015267 0ustar spectrestaff .word $c000 * = $c000 #if 0 #error BUGGGGG #endif #if 1 lda #93 jsr $ffd2 #endif /* comment this out to stop testing included gaffes */ #ifdef BUG #include "test.inc" #endif #if 1 #if 2 lda #93 jsr $ffd2 #endif #endif #ifdef X /* comment this out for bugs in this file */ #endif xa-2.3.8/tests/quotch/0000755000031500000010000000000013125354744014123 5ustar spectrestaffxa-2.3.8/tests/quotch/ok0000644000031500000010000000001613125351701014442 0ustar spectrestaff©;É:)"é; :I'xa-2.3.8/tests/quotch/test.s0000644000031500000010000000020613125351625015257 0ustar spectrestaff .word $9000 * = $9000 ; test specific single characters can be quoted LDA #';' CMP #':' AND #'"' SBC #";" ORA #":" EOR #"'" xa-2.3.8/tests/recmac/0000755000031500000010000000000013125354744014052 5ustar spectrestaffxa-2.3.8/tests/recmac/Makefile0000644000031500000010000000034612004347104015500 0ustar spectrestaffdefault: # this should fail. ../../xa -DFAIL test.asm || exit 0 && exit 1 # these should not fail. ../../xa test.asm ../hextool -cmp=test.ok < a.o65 ../../xa testi.asm ../hextool -cmp=testi.ok < a.o65 clean: rm -f a.o65 xa-2.3.8/tests/recmac/cpu.inc0000644000031500000010000000006110551222050015311 0ustar spectrestaff; ; FILE cpu.inc ; #define WDM(v) .byt $42,(v) xa-2.3.8/tests/recmac/test.asm0000644000031500000010000000065312004346551015527 0ustar spectrestaff#define AA 1 #define POKE(a,b) lda #b: sta a #define WW AA start ; next line works POKE(1, 2) ; next two lines work lda #AA sta 2 ; next line fails POKE(AA, 2) POKE(WW, 2) lda #WW sta 2 #define WW 94 POKE(WW, 2) #define WW 5 #define AA WW #define POKE(a,b) lda #a: sta b POKE(AA, 3) bne start rts /* this should bug out */ #ifdef FAIL POKE(NOGOOD, 7) #endif xa-2.3.8/tests/recmac/test.ok0000644000031500000010000000003712004346675015363 0ustar spectrestaff©…©…©…©…©…©…^©…Ðâ`xa-2.3.8/tests/recmac/testi.asm0000644000031500000010000000012310551344147015674 0ustar spectrestaff ; ; FILE image.a ; #include "cpu.inc" .text *=$C000 Foo: WDM(170) xa-2.3.8/tests/recmac/testi.ok0000644000031500000010000000000212004347000015503 0ustar spectrestaffBªxa-2.3.8/tests/relocundef/0000755000031500000010000000000013125354744014746 5ustar spectrestaffxa-2.3.8/tests/relocundef/Makefile0000644000031500000010000000131712004316314016372 0ustar spectrestaff default: all all: a.o65 b.o65 compare a.o65: test1.o65 @echo "********* This should give a warning about an undefined relocation table entry" ../../reloc65 -X test1.o65 ../hextool a.o65 > a.o65.hex b.o65: test2.o65 @echo "********* This should NOT give a warning" ../../reloc65 -X -o b.o65 test2.o65 ../hextool b.o65 > b.o65.hex test1.o65: test1.a65 ../../xa -R -Lundefl -Ll2 -o test1.o65 test1.a65 ../hextool test1.o65 > test1.o65.hex test2.o65: test2.a65 ../../xa -R -o test2.o65 test2.a65 ../hextool test2.o65 > test2.o65.hex compare: ../hextool -cmp=a.ok < a.o65 ../hextool -cmp=b.ok < b.o65 clean: rm -f test1.o65 a.o65 test1.o65.hex a.o65.hex rm -f test2.o65 b.o65 test2.o65.hex b.o65.hex xa-2.3.8/tests/relocundef/a.ok0000644000031500000010000000001112004316263015476 0ustar spectrestaff¢­ÊÐú`xa-2.3.8/tests/relocundef/b.ok0000644000031500000010000000001112004316266015502 0ustar spectrestaff¢­ÊÐú`xa-2.3.8/tests/relocundef/test1.a650000644000031500000010000000013110546755074016323 0ustar spectrestaff // this file defines an undefined label .text ldx #1 l1 lda undefl dex bne l1 rts xa-2.3.8/tests/relocundef/test2.a650000644000031500000010000000014412004316247016312 0ustar spectrestaff // this file defines an undefined label .text ldx #1 l1 lda undefl dex bne l1 rts undefl =1 xa-2.3.8/vstudio/0000755000031500000010000000000010630200472013135 5ustar spectrestaffxa-2.3.8/vstudio/00readme.txt0000644000031500000010000000062202630400772015301 0ustar spectrestaffThis directory contains a solution and project files that can be used to build xa and the various tools in the misc directory with the free version of Microsoft Visual C++ 2005 (AKA Visual Studio 2005 Express). This compiler and IDE can be dowloaded free from http://msdn.microsoft.com/vstudio/express/downloads/default.aspx Just run visual studio and load the solution called "vstudio.sln" xa-2.3.8/vstudio/file65.vcproj0000644000031500000010000000753202630376320015472 0ustar spectrestaff xa-2.3.8/vstudio/ldo65.vcproj0000644000031500000010000000752702630376320015335 0ustar spectrestaff xa-2.3.8/vstudio/printcbm.vcproj0000644000031500000010000000754002630376320016215 0ustar spectrestaff xa-2.3.8/vstudio/uncpk.vcproj0000644000031500000010000000752702630374614015530 0ustar spectrestaff xa-2.3.8/vstudio/vstudio.sln0000644000031500000010000000515502630374470015371 0ustar spectrestaff Microsoft Visual Studio Solution File, Format Version 9.00 # Visual C++ Express 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xa", "xa.vcproj", "{55808FFA-DA3B-44AF-AB9E-D937A531F932}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uncpk", "uncpk.vcproj", "{32CE058C-D818-4756-BAA6-A8AD4378308D}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "file65", "file65.vcproj", "{3CB15D2B-3777-4401-BF81-C0BC1B8AE8E6}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ldo65", "ldo65.vcproj", "{EFA4F295-A2CD-4B8A-ABE9-DD9DEB670CA6}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "printcbm", "printcbm.vcproj", "{26727633-7B9B-40CB-A31A-C6C6FEBA00CA}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {55808FFA-DA3B-44AF-AB9E-D937A531F932}.Debug|Win32.ActiveCfg = Debug|Win32 {55808FFA-DA3B-44AF-AB9E-D937A531F932}.Debug|Win32.Build.0 = Debug|Win32 {55808FFA-DA3B-44AF-AB9E-D937A531F932}.Release|Win32.ActiveCfg = Release|Win32 {55808FFA-DA3B-44AF-AB9E-D937A531F932}.Release|Win32.Build.0 = Release|Win32 {32CE058C-D818-4756-BAA6-A8AD4378308D}.Debug|Win32.ActiveCfg = Debug|Win32 {32CE058C-D818-4756-BAA6-A8AD4378308D}.Debug|Win32.Build.0 = Debug|Win32 {32CE058C-D818-4756-BAA6-A8AD4378308D}.Release|Win32.ActiveCfg = Release|Win32 {32CE058C-D818-4756-BAA6-A8AD4378308D}.Release|Win32.Build.0 = Release|Win32 {3CB15D2B-3777-4401-BF81-C0BC1B8AE8E6}.Debug|Win32.ActiveCfg = Debug|Win32 {3CB15D2B-3777-4401-BF81-C0BC1B8AE8E6}.Debug|Win32.Build.0 = Debug|Win32 {3CB15D2B-3777-4401-BF81-C0BC1B8AE8E6}.Release|Win32.ActiveCfg = Release|Win32 {3CB15D2B-3777-4401-BF81-C0BC1B8AE8E6}.Release|Win32.Build.0 = Release|Win32 {EFA4F295-A2CD-4B8A-ABE9-DD9DEB670CA6}.Debug|Win32.ActiveCfg = Debug|Win32 {EFA4F295-A2CD-4B8A-ABE9-DD9DEB670CA6}.Debug|Win32.Build.0 = Debug|Win32 {EFA4F295-A2CD-4B8A-ABE9-DD9DEB670CA6}.Release|Win32.ActiveCfg = Release|Win32 {EFA4F295-A2CD-4B8A-ABE9-DD9DEB670CA6}.Release|Win32.Build.0 = Release|Win32 {26727633-7B9B-40CB-A31A-C6C6FEBA00CA}.Debug|Win32.ActiveCfg = Debug|Win32 {26727633-7B9B-40CB-A31A-C6C6FEBA00CA}.Debug|Win32.Build.0 = Debug|Win32 {26727633-7B9B-40CB-A31A-C6C6FEBA00CA}.Release|Win32.ActiveCfg = Release|Win32 {26727633-7B9B-40CB-A31A-C6C6FEBA00CA}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal xa-2.3.8/vstudio/xa.vcproj0000644000031500000010000001235302630374566015017 0ustar spectrestaff