Mercurial > hg > Members > kono > os9 > sbc09
changeset 57:2088fd998865
sbc09 directry clean up
line wrap: on
line diff
--- a/.gdbinit Mon Jul 23 10:52:33 2018 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -handle 2 pass -define regs -call (void)printf("rax=%08lx rbx=%08lx rcx=%08lx rdx=%08lx\nrsi=%08lx rdi=%08lx rbp=%08lx rsp=%08lx rip=%08lx\n",$rax,$rbx,$rcx,$rdx,$rsi,$rdi,$rbp,$rsp,$rip) -end -define si -stepi -regs -x/1i $rip -end -define ni -nexti -regs -x/1i $rip -end -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AUTHORS Mon Jul 23 16:07:12 2018 +0900 @@ -0,0 +1,8 @@ + +AUTHORS are and/or have been: + +* Lennart Benschop: http://lennartb.home.xs4all.nl/m6809.html +* Jens Diemer: http://www.jensdiemer.de/ +* Johann E. Klasek: http://klasek.at/hc/6809/ + +basic.asm created 20-OCT-77 by John Byrns \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LICENSE Mon Jul 23 16:07:12 2018 +0900 @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/> + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + Lennart Benschop 6809 Single Board Computer + Copyright (C) 1993 L.C. Benschop, Eidnhoven The Netherlands + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + {signature of Ty Coon}, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. \ No newline at end of file
--- a/Makefile Mon Jul 23 10:52:33 2018 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -# -# Makefile Sim6809 -# -# created 1994 by L.C. Benschop -# 2013-10-28 - Jens Diemer: add "clean" section -# 2014-06-25 - J.E. Klasek -# -# copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details. -# license: GNU General Public License version 2, see LICENSE for more details. -# - -# CFLAGS=-O3 -fomit-frame-pointer -DTERM_CONTROL -CFLAGS=-g -DTERM_CONTROL - -V09FLAGS= -DUSE_TERMIOS #-DBIG_ENDIAN - - -SIM_BIN=v09s v09st - -APPS=mon2.s - -# will be installed to ".." -BIN=a09 v09 v09c d09 $(SIM_BIN) v09.rom - -TARGETS=$(BIN) $(APPS) - -OTHER=monitor.s makerom - -all: $(TARGETS) - -# ------------------------------------ - -a09 : a09.o os9crc.o - $(CC) $(CFLAGS) $(V09FLAGS) a09.o os9crc.o -o $@ - -v09: v09.o engine.o io.o d09.o trace.o vdisk.o - $(CC) -o v09 $(CFLAGS) v09.o engine.o io.o d09.o trace.o vdisk.o - -# with Coco MMU -v09c: v09.c engine.c io.c d09.o trace.o vdisk.o - $(CC) -o v09c $(CFLAGS) $(V09FLAGS) -DIOPAGE=0xff80 -DUSE_MMU=1 -DUSE_VDISK v09.c engine.c io.c d09.o trace.c vdisk.c - -a09.o : a09.c - $(CC) -c $(CFLAGS) $(V09FLAGS) $< - -v09.o: v09.c - $(CC) -c $(CFLAGS) $(V09FLAGS) $< - -d09 : d09.c - $(CC) -Wno-format-security $(CFLAGS) $(V09FLAGS) $< -o $@ - -d09.o : d09.c - $(CC) -c -DNO_MAIN -Wno-format-security $(CFLAGS) $(V09FLAGS) $< - -engine.o: engine.c - $(CC) -c $(CFLAGS) $(V09FLAGS) $< - -io.o: io.c - $(CC) -c $(CFLAGS) -DUSE_VDISK $(V09FLAGS) $< - -vdisk.o: vdisk.c v09.h - $(CC) -c $(CFLAGS) $(V09FLAGS) $< - -trace.o: trace.c v09.h - $(CC) -c $(CFLAGS) $(V09FLAGS) $< - -v09.rom: makerom monitor.s - ./makerom <monitor.s - -monitor.s: monitor.asm - ./a09 -s monitor.s -l monitor.lst monitor.asm - -mon2.s: mon2.asm - ./a09 -s mon2.s -l mon2.lst mon2.asm - -makerom: makerom.c - $(CC) -o makerom makerom.c - -# ------------------------------------ - -v09s: v09s.c - $(CC) $(CFLAGS) -o $@ $< - -v09st: v09s.c - $(CC) $(CFLAGS) -DTRACE -o $@ $< - -# ------------------------------------ - -install: - -for bin in $(BIN); do \ - [ -r $$bin ] && cp -p $$bin .. && echo "installing ../$$bin ..." ;\ - done ;\ - exit 0 - -# ------------------------------------ - -cleanall: clean - rm -rf $(TARGETS) $(OTHER) - (cd ..; rm -rf $(BIN) ) - -realclean: cleanall - -clean: - rm -rf core *.BAK *.o *.lst *.dSYM - -# ------------------------------------ - -# DO NOT DELETE - -engine.o: v09.h -io.o: v09.h -trace.o: v09.h -v09.o: v09.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README-os9.txt Mon Jul 23 16:07:12 2018 +0900 @@ -0,0 +1,166 @@ +6809 Simulator/Emulator for OS9 +======================= + +sbc09 stands for Lennart Benschop 6809 Single Board Computer. +It contains a assembler and simulator for the Motorola M6809 processor. + +copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details. +license: GNU General Public License version 2, see LICENSE for more details. + + +Forum thread: http://archive.worldofdragon.org/phpBB3/viewtopic.php?f=8&t=4880 +Project: https://github.com/6809/sbc09 + + +For the usage of the assembler a09 and 6809 single board system v09 +read doc/sbc09.creole! + + +This distribution includes + 1. The 6809 single board system as a stand alone environment built as v09 + 1. with CoCo like MMU v09c + +How to make +--------- + + make clean; make + + +How to run +--------- + + make lv1 + +or + + make lv2 + +vrbf mount current directory on /v0, put os9 command there. + +You can add os9 disk image using -0 or -1 option ( ex. https://github.com/sorenroug/osnine-java.git ) + + src/v09 -rom src/os9/os9lv1.rom -0 OS9.dsk -1 WORK.dsk + + src/v09c -rom src/os9/os9lv2.rom -0 OS9.dsk -1 WORK.dsk + + +Structure +--------- + +src/ + a09.c + The 6809 assembler. It's fairly portable (ANSI) C. It works on Unix + + Features of the assembler: + - os9 directives + - Statements MACRO, PUBLIC, EXTERN IF/ELSE/ENDIF INCLUDE not yet + implemented. + + v09.c + engine.c + io.c + trace.c + The 6809 single board simulator/emulator v09. + -DUSE_MMU to use MMU + vdisk.c + mount current directory on /v0 using VRBF + + d09.c + 6809 disassembler with os9 feature + + os9/ + makerom.c make rom for level1 and level2 + os9mod.c check os9 module + -s skip fill bytes + crc.c os9 crc checker + level1 os9 level1 module + clock.asm + d0.asm + d1.asm + v0.asm + init.asm + pdisk.asm + printer.asm + pty-dd.asm + pty.asm + level2 os9 level2 module + boot.asm + defsfile + init.asm + clock.asm + sysgo.asm + vector.asm + vrbf.asm virtual rbf manager + v0.asm + +v09/v09c feature + + Usage: v09 [-rom rom-image] [-t tracefile [-tl addr] [-nt][-th addr] ] [-e escchar] + [-0 diskImage0] [-1 diskImage1] + + Usage: v09 [-rom rom-image] [-t tracefile [-tl addr] [-nt][-th addr] ] [-e escchar] + [-0 diskImage0] [-1 diskImage1] + + -nt start with trace on + -rom options use irq ( not firq ) timer, timer will not start until timer IO command + vrbf default is a current directory + +v09 tracing command ( may be very slow ) + + v09>h + s [count] one step trace (default) + n step over call or os9 system call + f finish this call (until stack pop) (unreliable) + b [adr] set break / watch point (on current physical address) + it stoped on pc==adr or value of adr was changed + B break / watch point list + d [n] delte break point list + c [count] continue; + x disassemble on pc + x [adr] [count] dump + xp page [adr] [count] mmu page dump + xi [adr] [count] disassemble + 0 file disk drive 0 image + 1 file disk drive 1 image + L file start log to file + S file set input file + X exit + q exit + U file upload from srecord file + D file download to srecord file + R do reset (unreliable) + h,? print this + + to see GIME + x 0xff90 + +a09 Assembler for os9 +------------- + + mod eom,name,tylg,atrv,start,size define os9 mod with crc + . data pointer ( same as *, only works just after the mod ) + * code pointer + emod + + os9 os9 system call + end + + fcs generates os9 string with 8th bit on termination + + use use os9 sources ( subsequent use/lib follow the directories ) + + accepts some more chars in names such as $ . _ + + +Links/References +================ + + +Project: + https://github.com/6809/sbc09 + Maintained by the original author and others. + +Source: + http://groups.google.com/group/alt.sources/browse_thread/thread/8bfd60536ec34387/94a7cce3fdc5df67 + Autor: Lennart Benschop lennart@blade.stack.urc.tue.nl, + lennartb@xs4all.nl (Webpage, Subject must start with "Your Homepage"!)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.txt Mon Jul 23 16:07:12 2018 +0900 @@ -0,0 +1,417 @@ +6809 Simulator/Emulator with os9 level1/level2 + Shini KONO (kono@ie.u-ryukyu.ac.jp) Mon Jul 23 10:59:06 JST 2018 + + using nitros9 + hg clone http://hg.code.sf.net/p/nitros9/code nitros9-code + + This emulator support vrbf ( simulate unix directory as a rbf disk ) and + ROM based boot. + + make clean; make + + to run lv1 or lv2 + + make lv1 + or + make lv2 + +======================= + +sbc09 stands for Lennart Benschop 6809 Single Board Computer. +It contains a assembler and simulator for the Motorola M6809 processor. + +copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details. +license: GNU General Public License version 2, see LICENSE for more details. + + +Forum thread: http://archive.worldofdragon.org/phpBB3/viewtopic.php?f=8&t=4880 +Project: https://github.com/6809/sbc09 + + +For the usage of the assembler a09 and 6809 single board system v09 +read doc/sbc09.creole! + + +This distribution includes two different kinds of simulators: + 1. The old sim6809 based "simple" simulator built as v09s, v09st + 2. The 6809 single board system as a stand alone environment built as v09 + + + +Structure +--------- + +src/ + Source for the developement tools and virtual machines ... + + a09.c + The 6809 assembler. It's fairly portable (ANSI) C. It works on both + Unix and DOS (TC2.0). + + Features of the assembler: + - generates binary file starting at the first address + where code is actually generated. So an initial block of RMB's + (maybe at a different ORG) is not included in the file. + - Accepts standard syntax. + - full expression evaluator. + - Statements SET, MACRO, PUBLIC, EXTERN IF/ELSE/ENDIF INCLUDE not yet + implemented. Some provisions are already made internally for macros + and/or relocatable objects. + + v09s.c + The (old) 6809 simulator. Loads a binary image (from a09) at adress $100 + and starts executing. SWI2 and SWI3 are for character output/input. + SYNC stops simulation. When compiling set -DBIG_ENDIAN if your + computer is big-endian. Set TERM_CONTROL for a crude single character + (instead of ANSI line-by-line) input. Works on Unix. + + v09stc.c + Same as v09s.c but for Turbo C. Has its own term control. + + v09.c + engine.c + io.c + The 6809 single board simulator/emulator v09. + + mon2.asm + Monitor progam, alternative version of monitor.asm + (used in ROM image alt09.rom) + + monitor.asm + Monitor progam (used in ROM image v09.rom for v09) + + makerom.c + Helper tool to generate ROM images for v09. + + +basic/ + Basic interpreters ... + + basic.asm + Tiny Basic + fbasic.asm + Tiny Basic with Lennarts floating point routines. + + +doc/ + Documentation ... + + +examples/ + Several test and benchmark programs, simple routines and some bigger stuff + like a Forth system (ef09). + + ef09.asm Implementation of E-Forth, a very rudimentary and portable Forth. + Type WORDS to see what words you have. You can evaluate RPN integer + expressions, like "12 34 + 5 * . " You can make new words like + " : SQUARED DUP * ; " etc. + + +examples_forth/ + Forth environment with examples. + For the 6809 single board system. + + + + +Notes on Linux Fedora Core 6 +---------------------------- +2012-06-04 + +Compiling v09s, v09st: + + * BIG_ENDIAN (already used by LINUX itself, changed to CPU_BIG_ENDIAN) + Now automatically set according to BIG_ENDIAN and BYTE_ORDER + if existing. + + * If TERM_CONTROL mode is active the keyboard is not really in raw mode - + keyboard signals are still allowed. + + * A tracefilter based on register values can be placed in the TRACE area to + get tracing output triggered by special states + + + +a09 Assembler +------------- + +Bugfixes: + * addres modes a,INDEXREG b,INDEXREG d,INDEXREG now known + as *legal*! + +Extended version: + http://lennartb.home.xs4all.nl/A09.c + (see above) + + * options -x and -s produces output in Intel Binary/Srecord format, + contains the above mentioned bugfixes (but fixed by the original + author). + + + + +v09s* Simulator +--------------- + +### CC register + +E F H I N Z V C Flag +8 7 6 5 4 3 2 1 Bit +| | | | | | | | +| | | | | | | +- $01 +| | | | | | +--- $02 +| | | | | +----- $04 +| | | | +------- $08 +| | | +--------- $10 +| | +----------- $20 +| +------------- $40 ++--------------- $80 + + +# differences from real 6809: + +ldd #$0fc9 +addb #$40 +adca #$00 + +H is set on VCC but not on real 6809, sim6809 does what? + + +### special behavior + + swi2 output character (STDOUT) in register B + swi3 read character from keyboard into register B + sync exit simulator + + +### start program +v09s BINARY + +### start program with tracing output on STDOUT +v09st BINARY + +### run program and leave memory dump (64k) + +# memory dump in file dump.v09 +v09s -d BINARY + + + +### Bugfixes + + * static int index; + otherwise the global C library function index() is referenced! + Write access on it leads to a core dump. + + * BIG_ENDIAN is not useable in FLAG because (POSIX?) Unix + (especially Linux) defines its byte order. + If BIG_ENDIAN == BYTE_ORDER -> architecture is big endian! + Changed to CPU_BIG_ENDIAN, which is refering BIG_ENDIAN and + BYTE_ORDER automatically (if existent). + + + + + + +eForth +------ + +Source: + + ef09.asm + + Backspace character changed from 127 to 8. + + +Memory-Layout: + + 0100 At this address the binary is placed to, the Forth entry point + 03C0 USER area start + 4000 Memory TOP + + +I/O: + Keyboard input: + * ^H or BSP deletes character + * RETURN -> interrupts (long) output + +Start: + + ../v09s ef09 + + +Bugs: + SEE ; + STAR (*) : * UM* DROP ; ... wrong, + : * M* DROP ; ... correct (sign!) + +Typical commands: + + Commands alway in upper case!!! + +WORD list of defined words of the current vocabulary + +BYE exit Forth (back to shell) +DUMP hex memory dump +SEE HL-word decompiler, corrected: + * stops at EXIT + * handles more special primitives (literals, strings, + variable, constants)) + * handles Direct Threading + * output line by line with address +.S shows the content of the parameter stack + +count FOR ... NEXT + replacement for + hi lo DO ... I ... LOOP + hi lo - 1+ FOR ... R@ lo + ... NEXT + + + + +Extensions: + + ZEQUAL 0= Primitive + PLUS1 1+ Primitive, added +2012-06-07 + ROLL ROLL HL, added + CONST CONSTANT HL, added + doCONST Primitive, added + +2012-06-08 + TWOSTAR 2* Primtive, added + TWOSLASH 2/ Primtive, added + MINUS1 1- Primtive, added + SWAPHL >< Primtive, added + STAR256 256* Primtive, added + SLASH256 256/ Primtive, added + CMOVE CMOVE Primtive + FILL FILL Primtive +2012-06-09 + ULESS U< Primitive + LESS < Primitive + DO DO HL, added + QDO ?DO HL, added + DODO (DO) Primitive, added + DOQDO (?DO) Primitive, added + LOOP LOOP HL, added + PLOOP +LOOP HL, added + DOLOOP (LOOP) Primitive, added + DOPLOOP (+LOOP) Primitive, added + +2012-06-11 + NEGAT NEGATE Primitive, alternative added + UMSTA UM* Primitive, but without MUL + LSHIFT LSHIFT Primitive, added + RSHIFT RSHIFT Primitive, added +2012-06-12 + LEAVE LEAVE Primitive, added (fig Forth) + MDO -DO HL, added + DOMDO (-DO) Primitive, added + I I Primitive, added (same as R@) + CMOVEW CMOVE Primitive, other implementation + STAR * korr.: uses M* (instead UM*) + BLANK BL Constant + +2012-06-19 + USLASH U/ Primitive, same as UM/MOD + UM/MOD uses USLASH + +2012-06-20 + DPLUS D+ Primitive + DSUB D- HL + ZERO 0 Constant + ONE 1 Constant + TWO 2 Constant + MONE -1 Constant + DOCLIT doCLIT Primitive +2012-06-21 + SEE SEE extended: handles LIT, CLIT +2012-06-22 + SEE SEE extended: handles + BRANCH,?BRANCH,?DO,-DO,LOOP,+LOOP,."..." + +2012-09-07 + SEE SEE ABORT", (DO) added, remarks corrected. + +TODO: + * XXX marks points to open issues. + * SEE command: + handling of + - [COMPILE] + - DOCONST, DOVAR, DOUSE + + +TEST: + +HEX ok +0 8000 8001 U/ . . FFFE 2 ok +FFFE 8001 U* . . U* ? ok +FFFE 8001 UM* . . 7FFF FFFE ok +FFFE 8001 UM* 2 0 D+ . . 8000 0 ok + +0 8000 7FFF U/ . . FFFF FFFF ok +0 FFFF FFFF U/ . . FFFF FFFF ok +0 FFFE FFFF U/ . . FFFE FFFE ok +FFFF FFFF UM* . . FFFE 1 ok +FFFF FFFE FFFF U/ . . FFFF FFFE ok + + + + + +Links/References +================ + + +Project: + https://github.com/6809/sbc09 + Maintained by the original author and others. + +Source: + http://groups.google.com/group/alt.sources/browse_thread/thread/8bfd60536ec34387/94a7cce3fdc5df67 + Autor: Lennart Benschop lennart@blade.stack.urc.tue.nl, + lennartb@xs4all.nl (Webpage, Subject must start with "Your Homepage"!) + + Newsgroups: alt.sources + From: lennart@blade.stack.urc.tue.nl (Lennart Benschop) + Date: 3 Nov 1993 15:21:16 GMT + Local: Mi 3 Nov. 1993 17:21 + Subject: 6809 assembler and simulator (examples) 2/2 + + +Homepage/Download links of Lennart Benschop: + http://lennartb.home.xs4all.nl/m6809.html + http://lennartb.home.xs4all.nl/sbc09.tar.gz + http://lennartb.home.xs4all.nl/A09.c + + +Emulator for 6809 written in Python, can run sbc09 ROM: + https://github.com/jedie/DragonPy/ + + +Newer posting in alt.sources (1994): + + Newsgroups: alt.sources + From: lenn...@blade.stack.urc.tue.nl (Lennart Benschop) + Date: 17 May 1994 08:13:25 GMT + Local: Di 17 Mai 1994 10:13 + Subject: 6809 assembler/simulator (3 of 3) + + +Referenced by: + + http://foldoc.org/6809 + Reference points to posting with buggy version from 1993. + + http://lennartb.home.xs4all.nl/m6809.html + BAD LINK: http://www.sandelman.ocunix.on.ca/People/Alan_DeKok/interests/6809.html + -> http://www.sandelman.ottawa.on.ca/People/Alan_DeKok/interests/ + 6809 specific site will be redirected, but does not exist. + + Internet-Archiv: + https://web.archive.org/web/20070112041235/http://www.striker.ottawa.on.ca/6809/ + 2014-05-01: Lennart B. lennartb@xs4all.nl has been informed. + + http://archive.worldofdragon.org/phpBB3/viewtopic.php?f=5&t=4308&start=60#p9750
--- a/a09.c Mon Jul 23 10:52:33 2018 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1695 +0,0 @@ -/* A09, 6809 Assembler2 - - created 1993,1994 by L.C. Benschop. - copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details. - license: GNU General Public License version 2, see LICENSE for more details. - THERE IS NO WARRANTY ON THIS PROGRAM. - - Generates binary image file from the lowest to - the highest address with actually assembled data. - - Machin edependencies: - char is 8 bits. - short is 16 bits. - integer arithmetic is twos complement. - - syntax a09 [-o filename] [-l filename] sourcefile. - - Options - -o filename name of the output file (default name minus a09 suffix) - -s filename name of the s-record output file (default its a binary file) - -l filename list file name (default no listing) - -d enable debugging - - recognized pseudoops: - extern public - macro endm if else endif - org equ set setdp - fcb fcw fdb fcc rmb - end include title - - Not all of these are actually IMPLEMENTED!!!!!! - - Revisions: - 1993-11-03 v0.1 - Initial version. - 1994/03/21 v0.2 - Fixed PC relative addressing bug - Added SET, SETDP, INCLUDE. IF/ELSE/ENDIF - No macros yet, and no separate linkable modules. - 2012-06-04 j at klasek at - New: debugging parameter/option. - Fixed additional possible issue PC relative addressing. - Compatibility: Octal number prefix "&". - 2014-07-15 j at klasek at - Fixed usage message. - 2018-07-11 - leax $ED00/256,x kernel offset in map - should be positive offset expr should be int(32bit) -*/ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <ctype.h> - -#define NLABELS 2048 -#define MAXIDLEN 16 -#define MAXLISTBYTES 8 -#define FNLEN 30 -#define LINELEN 128 - -static int debug=0; -static struct incl { - char *name; - struct incl *next; -} *incls = 0; - -static struct longer { - int gline; - int change; - struct longer *next; -} *lglist = 0; - - -struct oprecord{char * name; - unsigned char cat; - unsigned short code;}; - -/* Instruction categories: - 0 one byte oprcodes NOP - 1 two byte opcodes SWI2 - 2 opcodes w. imm byte ANDCC - 3 LEAX etc. - 4 short branches. BGE - 5 long branches 2byte opc LBGE - 6 long branches 1byte opc LBRA - 7 accumulator instr. ADDA - 8 double reg instr 1byte opc LDX - 9 double reg instr 2 byte opc LDY - 10 single address instrs NEG - 11 TFR, EXG - 12 push,pull - 13 pseudoops -*/ - -struct oprecord optable[]={ - {"ABX",0,0x3a},{"ADCA",7,0x89},{"ADCB",7,0xc9}, - {"ADDA",7,0x8b},{"ADDB",7,0xcb},{"ADDD",8,0xc3}, - {"ANDA",7,0X84},{"ANDB",7,0xc4},{"ANDCC",2,0x1c}, - {"ASL",10,0x08},{"ASLA",0,0x48},{"ASLB",0,0x58}, - {"ASR",10,0x07},{"ASRA",0,0x47},{"ASRB",0,0x57}, - {"BCC",4,0x24},{"BCS",4,0x25},{"BEQ",4,0x27}, - {"BGE",4,0x2c},{"BGT",4,0x2e},{"BHI",4,0x22}, - {"BHS",4,0x24},{"BITA",7,0x85},{"BITB",7,0xc5}, - {"BLE",4,0x2f},{"BLO",4,0x25},{"BLS",4,0x23}, - {"BLT",4,0x2d},{"BMI",4,0x2b},{"BNE",4,0x26}, - {"BPL",4,0x2a},{"BRA",4,0x20},{"BRN",4,0x21}, - {"BSR",4,0x8d}, - {"BVC",4,0x28},{"BVS",4,0x29}, - {"CLC",1,0x1cfe},{"CLF",1,0x1cbf},{"CLI",1,0x1cef}, - {"CLIF",1,0x1caf}, - {"CLR",10,0x0f},{"CLRA",0,0x4f},{"CLRB",0,0x5f}, - {"CLV",1,0x1cfd}, - {"CMPA",7,0x81},{"CMPB",7,0xc1},{"CMPD",9,0x1083}, - {"CMPS",9,0x118c},{"CMPU",9,0x1183},{"CMPX",8,0x8c}, - {"CMPY",9,0x108c}, - {"COM",10,0x03},{"COMA",0,0x43},{"COMB",0,0x53}, - {"CWAI",2,0x3c},{"DAA",0,0x19}, - {"DEC",10,0x0a},{"DECA",0,0x4a},{"DECB",0,0x5a}, - {"DES",1,0x327f},{"DEU",1,0x335f},{"DEX",1,0x301f}, - {"DEY",1,0x313f}, - {"ELSE",13,1}, - {"EMOD",13,25}, - {"END",13,2}, - {"ENDC",13,3}, - {"ENDIF",13,3}, - {"ENDM",13,4}, - {"EORA",7,0x88},{"EORB",7,0xc8}, - {"EQU",13,5},{"EXG",11,0x1e},{"EXTERN",13,6}, - {"FCB",13,7},{"FCC",13,8}, - {"FCS",13,23}, - {"FCW",13,9}, - {"FDB",13,9}, - {"IF",13,10}, - {"IFEQ",13,30}, - {"IFGT",13,29}, - {"IFNDEF",13,33}, - {"IFNE",13,28}, - {"IFP1",13,21}, - {"INC",10,0x0c},{"INCA",0,0x4c},{"INCB",0,0x5c}, - {"INCLUDE",13,16}, - {"INS",1,0x3261},{"INU",1,0x3341},{"INX",1,0x3001}, - {"INY",1,0x3121},{"JMP",10,0x0e},{"JSR",8,0x8d}, - {"LBCC",5,0x1024},{"LBCS",5,0x1025},{"LBEQ",5,0x1027}, - {"LBGE",5,0x102c},{"LBGT",5,0x102e},{"LBHI",5,0x1022}, - {"LBHS",5,0x1024}, - {"LBLE",5,0x102f},{"LBLO",5,0x1025},{"LBLS",5,0x1023}, - {"LBLT",5,0x102d},{"LBMI",5,0x102b},{"LBNE",5,0x1026}, - {"LBPL",5,0x102a},{"LBRA",6,0x16},{"LBRN",5,0x1021}, - {"LBSR",6,0x17}, - {"LBVC",5,0x1028},{"LBVS",5,0x1029}, - {"LDA",7,0x86},{"LDB",7,0xc6},{"LDD",8,0xcc}, - {"LDS",9,0x10ce},{"LDU",8,0xce},{"LDX",8,0x8e}, - {"LDY",9,0x108e},{"LEAS",3,0x32}, - {"LEAU",3,0x33},{"LEAX",3,0x30},{"LEAY",3,0x31}, - {"LSL",10,0x08},{"LSLA",0,0x48},{"LSLB",0,0x58}, - {"LSR",10,0x04},{"LSRA",0,0x44},{"LSRB",0,0x54}, - {"MACRO",13,11}, - {"MOD",13,24}, - {"MUL",0,0x3d}, - {"NAM",13,26}, - {"NEG",10,0x00},{"NEGA",0,0x40},{"NEGB",0,0x50}, - {"NOP",0,0x12}, - {"OPT",13,19}, - {"ORA",7,0x8a},{"ORB",7,0xca},{"ORCC",2,0x1a}, - {"ORG",13,12}, - {"OS9",13,32}, - {"PAG",13,20}, {"PAGE",13,20}, - {"PSHS",12,0x34},{"PSHU",12,0x36},{"PUBLIC",13,13}, - {"PULS",12,0x35},{"PULU",12,0x37},{"RMB",13,0}, - {"ROL",10,0x09},{"ROLA",0,0x49},{"ROLB",0,0x59}, - {"ROR",10,0x06},{"RORA",0,0x46},{"RORB",0,0x56}, - {"RTI",0,0x3b},{"RTS",0,0x39}, - {"SBCA",7,0x82},{"SBCB",7,0xc2}, - {"SEC",1,0x1a01},{"SEF",1,0x1a40},{"SEI",1,0x1a10}, - {"SEIF",1,0x1a50},{"SET",13,15}, - {"SETDP",13,14},{"SEV",1,0x1a02},{"SEX",0,0x1d}, - {"STA",7,0x87},{"STB",7,0xc7},{"STD",8,0xcd}, - {"STS",9,0x10cf},{"STU",8,0xcf},{"STX",8,0x8f}, - {"STY",9,0x108f}, - {"SUBA",7,0x80},{"SUBB",7,0xc0},{"SUBD",8,0x83}, - {"SWI",0,0x3f},{"SWI2",1,0x103f},{"SWI3",1,0x113f}, - {"SYNC",0,0x13},{"TFR",11,0x1f}, - {"TITLE",13,18}, - {"TST",10,0x0d},{"TSTA",0,0x4d},{"TSTB",0,0x5d}, - {"TTL",13,18}, - {"USE",13,27}, -}; - -struct symrecord{char name[MAXIDLEN+1]; - char cat; - unsigned short value; - struct symrecord *next; - }; - -int symcounter=0; -int os9 = 0; // os9 flag -int rmbmode = 0; // in os9 work area -struct symrecord * prevlp = 0; - -/* expression categories... - ECORD all zeros is ordinary constant. - ECADR bit 1 indicates address within module. - ECEXT bit 2 indicates external address. - ECLBL bit 3 public label - ECABS bit 4 indicates this can't be relocated if it's an address. - ECNEG bit 5 indicates address (if any) is negative. -*/ - - -/* Symbol categories. exprcat ( symcat & 0xe ) - 0 SCC Constant value (from equ). ECORD - 1 SCV Variable value (from set) ECORD - 2 SCC__ADR Address within program module (label). ECADR - 3 SCV__ADR Variable containing address. ECADR - 4 SC_E_ADR Adress in other program module (extern) ECEXT - 5 SCVE_ADR Variable containing external address. ECEXT - 6 SCU _ADR Unresolved address. ECEXT+ECADR - 7 SCV_UADR Variable containing unresolved address. ECEXT+ECADR - 8 SC___LBL Public label. ECLBL - 9 SCMACRO Macro definition. xxx - 10 SCU__LBL Public label (yet undefined). ECADR+ECLBL - 11 SCPARAM parameter name. ECADR+ECLBL - 12 SCLOCAL local label. ECEXT+ECLBL - 13 SCEMPTY empty. xxx -*/ - -struct symrecord symtable[NLABELS]; - -void processfile(char *name); - -struct oprecord * findop(char * nm) -/* Find operation (mnemonic) in table using binary search */ -{ - int lo,hi,i,s; - lo=0;hi=sizeof(optable)/sizeof(optable[0])-1; - do { - i=(lo+hi)/2; - s=strcmp(optable[i].name,nm); - if(s<0) lo=i+1; - else if(s>0) hi=i-1; - else break; - } while(hi>=lo); - if (s) return NULL; - return optable+i; -} - -struct symrecord * findsym(char * nm) { -/* finds symbol table record; inserts if not found - uses binary search, maintains sorted table */ - int lo,hi,i,j,s; - lo=0;hi=symcounter-1; - s=1;i=0; - while (hi>=lo) { - i=(lo+hi)/2; - s=strcmp(symtable[i].name,nm); - if(s<0) lo=i+1; - else if(s>0) hi=i-1; - else break; - } - if(s) { - i=(s<0?i+1:i); - if(symcounter==NLABELS) { - fprintf(stderr,"Sorry, no storage for symbols!!!"); - exit(4); - } - for(j=symcounter;j>i;j--) { - struct symrecord *from = &symtable[j-1]; - if (prevlp == from) prevlp++; - if (from->next && from->next - symtable > i) from->next ++; - symtable[j]=symtable[j-1]; - } - symcounter++; - strcpy(symtable[i].name,nm); - symtable[i].cat=13; - } - return symtable+i; -} - -FILE *listfile,*objfile; -char *listname,*objname,*srcname,*curname; -int lineno,glineno; - -void -outsymtable() -{ - int i,j=0; - fprintf(listfile,"\nSYMBOL TABLE"); - for(i=0;i<symcounter;i++) - if(symtable[i].cat!=13) { - if(j%4==0)fprintf(listfile,"\n"); - fprintf(listfile,"%10s %02d %04x",symtable[i].name,symtable[i].cat, - symtable[i].value); - j++; - } - fprintf(listfile,"\n"); -} - -struct regrecord{char *name;unsigned char tfr,psh;}; -struct regrecord regtable[]= - {{"D",0x00,0x06},{"X",0x01,0x10},{"Y",0x02,0x20}, - {"U",0x03,0x40},{"S",0x04,0x40},{"PC",0x05,0x80}, - {"A",0x08,0x02},{"B",0x09,0x04},{"CC",0x0a,0x01}, - {"CCR",0x0a,0x01},{"DP",0x0b,0x08},{"DPR",0x0b,0x08}}; - -struct regrecord * findreg(char *nm) -{ - int i; - for(i=0;i<12;i++) { - if(strcmp(regtable[i].name,nm)==0) return regtable+i; - } - return 0; -} - - -char pass; /* Assembler pass=1 or 2 */ -char listing; /* flag to indicate listing */ -char relocatable; /* flag to indicate relocatable object. */ -char terminate; /* flag to indicate termination. */ -char generating; /* flag to indicate that we generate code */ -unsigned short loccounter,oldlc,prevloc,rmbcounter; /* Location counter */ - -char inpline[128]; /* Current input line (not expanded)*/ -char srcline[128]; /* Current source line */ -char * srcptr; /* Pointer to line being parsed */ - -char unknown; /* flag to indicate value unknown */ -char certain; /* flag to indicate value is certain at pass 1*/ -int error; /* flags indicating errors in current line. */ -int errors; /* number of errors */ -char exprcat; /* category of expression being parsed, eg. - label or constant, this is important when - generating relocatable object code. */ - -void makelonger(int gl) { - if (pass==1) return; - for(struct longer *p=lglist;p;p=p->next) { - if (p->gline==gl) { // already fixed - p->change = 1; - return; - } - } - struct longer *p = (struct longer *)calloc(sizeof(struct longer *),1); - p->gline=gl; - p->next = lglist; - lglist = p; -} - -int longer() { - for(struct longer *p=lglist;p;p=p->next) { - if (p->change == 0) return 1; - } - return 0; -} -void generate() -{ - generating = 1; - if (rmbmode) { - rmbcounter = loccounter; - oldlc = loccounter = prevloc; - rmbmode = 0; - } -} - - -char namebuf[MAXIDLEN+1]; - -void -err(int er) { - error |= er ; -} - -void -scanname() -{ - int i=0; - char c; - while(1) { - c=*srcptr++; - if(c>='a'&&c<='z')c-=32; - if(c!='_'&&c!='@'&&c!='.'&&c!='$'&&(c<'0'||c>'9')&&(c<'A'||c>'Z'))break; - if(i<MAXIDLEN)namebuf[i++]=c; - } - namebuf[i]=0; - srcptr--; -} - -void -skipspace() -{ - char c; - do { - c=*srcptr++; - } while(c==' '||c=='\t'); - srcptr--; -} - -int scanexpr(int); - -int scandecimal() -{ - char c; - int t=0; - c=*srcptr++; - while(isdigit(c)) { - t=t*10+c-'0'; - c=*srcptr++; - } - srcptr--; - return t; -} - -int scanhex() -{ - int t=0,i=0; - srcptr++; - scanname(); - while(namebuf[i]>='0'&&namebuf[i]<='F') { - t=t*16+namebuf[i]-'0'; - if(namebuf[i]>'9')t-=7; - i++; - } - if(i==0)error|=1; - return t; -} - -int scanchar() -{ - int t; - srcptr++; - t=*srcptr; - if(t)srcptr++; - if (*srcptr=='\'')srcptr++; - return t; -} - -int scanbin() -{ - char c; - int t=0; - srcptr++; - c=*srcptr++; - while(c=='0'||c=='1') { - t=t*2+c-'0'; - c=*srcptr++; - } - srcptr--; - return t; -} - -int scanoct() -{ - char c; - int t=0; - srcptr++; - c=*srcptr++; - while(c>='0'&&c<='7') { - t=t*8+c-'0'; - c=*srcptr++; - } - srcptr--; - return t; -} - - -int scanlabel() -{ - struct symrecord * p; - scanname(); - p=findsym(namebuf); - if(p->cat==13) { - p->cat=6; - p->value=0; - } - if(p->cat==9||p->cat==11)error|=1; - exprcat=p->cat&14; - if(exprcat==6||exprcat==10)unknown=1; - if(((exprcat==2||exprcat==8) - && (unsigned short)(p->value)>(unsigned short)loccounter)|| - exprcat==4) - certain=0; - if(exprcat==8||exprcat==6||exprcat==10)exprcat=2; - return p->value; -} - - -int scanfactor() -{ - char c; - int t; - skipspace(); - c=*srcptr; - if(isalpha(c))return scanlabel(); - else if(isdigit(c))return scandecimal(); - else switch(c) { - case '*' : srcptr++;exprcat|=2; if(rmbmode) return prevloc; else return loccounter; - case '.' : srcptr++;exprcat|=2; if(os9&&!rmbmode) return rmbcounter; else return loccounter; - case '$' : return scanhex(); - case '%' : return scanbin(); - case '&' : /* compatibility */ - case '@' : return scanoct(); - case '\'' : return scanchar(); - case '(' : srcptr++;t=scanexpr(0);skipspace(); - if(*srcptr==')')srcptr++;else error|=1; - return t; - case '-' : srcptr++;exprcat^=32;return -scanfactor(); - case '+' : srcptr++;return scanfactor(); - case '!' : srcptr++;exprcat|=16;return !scanfactor(); - case '^' : - case '~' : srcptr++;exprcat|=16;return ~scanfactor(); - } - error|=1; - return 0; -} - -#define EXITEVAL {srcptr--;return t;} - -#define RESOLVECAT if((oldcat&15)==0)oldcat=0;\ - if((exprcat&15)==0)exprcat=0;\ - if((exprcat==2&&oldcat==34)||(exprcat==34&&oldcat==2)) {\ - exprcat=0;\ - oldcat=0;}\ - exprcat|=oldcat;\ -/* resolve such cases as constant added to address or difference between - two addresses in same module */ - - -int scanexpr(int level) /* This is what you call _recursive_ descent!!!*/ -{ - int t,u; - char oldcat,c; - exprcat=0; - if(level==10)return scanfactor(); - t=scanexpr(level+1); - while(1) { - // skipspace(); - c=*srcptr++; - switch(c) { - case '*':oldcat=exprcat; - t*=scanexpr(10); - exprcat|=oldcat|16; - break; - case '/':oldcat=exprcat; - u=scanexpr(10); - if(u)t/=u;else error|=1; - exprcat|=oldcat|16; - break; - case '%':oldcat=exprcat; - u=scanexpr(10); - if(u)t%=u;else error|=1; - exprcat|=oldcat|16; - break; - case '+':if(level==9)EXITEVAL - oldcat=exprcat; - t+=scanexpr(9); - RESOLVECAT - break; - case '-':if(level==9)EXITEVAL - oldcat=exprcat; - t-=scanexpr(9); - exprcat^=32; - RESOLVECAT - break; - case '<':if(*(srcptr)=='<') { - if(level>=8)EXITEVAL - srcptr++; - oldcat=exprcat; - t<<=scanexpr(8); - exprcat|=oldcat|16; - break; - } else if(*(srcptr)=='=') { - if(level>=7)EXITEVAL - srcptr++; - oldcat=exprcat; - t=t<=scanexpr(7); - exprcat|=oldcat|16; - break; - } else { - if(level>=7)EXITEVAL - oldcat=exprcat; - t=t<scanexpr(7); - exprcat|=oldcat|16; - break; - } - case '>':if(*(srcptr)=='>') { - if(level>=8)EXITEVAL - srcptr++; - oldcat=exprcat; - t>>=scanexpr(8); - exprcat|=oldcat|16; - break; - } else if(*(srcptr)=='=') { - if(level>=7)EXITEVAL - srcptr++; - oldcat=exprcat; - t=t>=scanexpr(7); - exprcat|=oldcat|16; - break; - } else { - if(level>=7)EXITEVAL - oldcat=exprcat; - t=t>scanexpr(7); - exprcat|=oldcat|16; - break; - } - case '!':if(level>=6) { - if (*srcptr=='=') { - srcptr++; - oldcat=exprcat; - t=t!=scanexpr(6); - exprcat|=oldcat|16; - } else { - oldcat=exprcat; - t|=scanexpr(6); - exprcat|=oldcat|16; - } - } - break; - case '=':if(level>=6)EXITEVAL - if(*srcptr=='=')srcptr++; - oldcat=exprcat; - t=t==scanexpr(6); - exprcat|=oldcat|16; - break; - case '&':if(level>=5)EXITEVAL - oldcat=exprcat; - t&=scanexpr(5); - exprcat|=oldcat|16; - break; - case '^':if(level>=4)EXITEVAL - oldcat=exprcat; - t^=scanexpr(4); - exprcat|=oldcat|16; - break; - case '|':if(level>=3)EXITEVAL - oldcat=exprcat; - t|=scanexpr(3); - exprcat|=oldcat|16; - default: EXITEVAL - } - } -} - -char mode; /* addressing mode 0=immediate,1=direct,2=extended,3=postbyte - 4=pcrelative(with postbyte) 5=indirect 6=pcrel&indirect*/ -char opsize; /*desired operand size 0=dunno,1=5,2=8,3=16*/ -short operand; -unsigned char postbyte; - -int dpsetting; - - -int scanindexreg() -{ - char c; - c=*srcptr; - if(islower(c))c-=32; - if (debug) fprintf(stderr,"DEBUG: scanindexreg: indexreg=%d, mode=%d, opsize=%d, error=%d, postbyte=%02X\n",c,mode,opsize,error,postbyte); - switch(c) { - case 'X':return 1; - case 'Y':postbyte|=0x20;return 1; - case 'U':postbyte|=0x40;return 1; - case 'S':postbyte|=0x60;return 1; - default: return 0; - } -} - -void -set3() -{ - if(mode<3)mode=3; -} - -void -scanspecial() -{ - set3(); - skipspace(); - if(*srcptr=='-') { - srcptr++; - if(*srcptr=='-') { - srcptr++; - postbyte=0x83; - } else postbyte=0x82; - if(!scanindexreg())error|=2;else srcptr++; - } else { - postbyte=0x80; - if(!scanindexreg())error|=2;else srcptr++; - if(*srcptr=='+') { - srcptr++; - if(*srcptr=='+') { - srcptr++; - postbyte+=1; - } - } else postbyte+=4; - } -} - -void -scanindexed() -{ - set3(); - postbyte=0; - if(scanindexreg()) { - srcptr++; - if(opsize==0) { - if(unknown||!certain)opsize=3; - else if(operand>=-16&&operand<16&&mode==3)opsize=1; - else if(operand>=-128&&operand<128)opsize=2; - else opsize=3; - } - switch(opsize) { - case 1:postbyte+=(operand&31);opsize=0;break; - case 2:postbyte+=0x88;break; - case 3:postbyte+=0x89;break; - } - } else { /*pc relative*/ - if(toupper(*srcptr)!='P')error|=2; - else { - srcptr++; - if(toupper(*srcptr)!='C')error|=2; - else { - srcptr++; - if(toupper(*srcptr)=='R')srcptr++; - } - } - mode++;postbyte+=0x8c; - if(opsize==1)opsize=2; - } -} - -#define RESTORE {srcptr=oldsrcptr;c=*srcptr;goto dodefault;} - -void -scanoperands() -{ - char c,d,*oldsrcptr; - unknown=0; - opsize=0; - certain=1; - skipspace(); - c=*srcptr; - mode=0; - if(c=='[') { - srcptr++; - c=*srcptr; - mode=5; - } - if (debug) fprintf(stderr,"DEBUG: scanoperands: c=%c (%02X)\n",c,c); - switch(c) { - case 'D': case 'd': - oldsrcptr=srcptr; - srcptr++; - skipspace(); - if(*srcptr!=',')RESTORE else { - postbyte=0x8b; - srcptr++; - if(!scanindexreg())RESTORE else {srcptr++;set3();} - } - break; - case 'A': case 'a': - oldsrcptr=srcptr; - srcptr++; - skipspace(); - if(*srcptr!=',')RESTORE else { - postbyte=0x86; - srcptr++; - if(!scanindexreg())RESTORE else {srcptr++;set3();} - } - break; - case 'B': case 'b': - oldsrcptr=srcptr; - srcptr++; - skipspace(); - if(*srcptr!=',')RESTORE else { - postbyte=0x85; - srcptr++; - if (debug) fprintf(stderr,"DEBUG: scanoperands: breg preindex: c=%c (%02X)\n",*srcptr,*srcptr); - if(!scanindexreg())RESTORE else {srcptr++;set3();} - if (debug) fprintf(stderr,"DEBUG: scanoperands: breg: postindex c=%c (%02X)\n",*srcptr,*srcptr); - } - break; - case ',': - srcptr++; - scanspecial(); - break; - case '#': - if(mode==5)error|=2;else mode=0; - srcptr++; - if (*srcptr=='"') { - operand = (srcptr[1]<<8) + srcptr[2] ; - srcptr += 3; - break; - } - operand=scanexpr(0); - break; - case '<': - srcptr++; - if(*srcptr=='<') { - srcptr++; - opsize=1; - } else opsize=2; - goto dodefault; - case '>': - srcptr++; - opsize=3; - default: dodefault: - operand=scanexpr(0); - skipspace(); - if(*srcptr==',') { - srcptr++; - scanindexed(); - } else { - if(opsize==0) { - if(unknown||!certain||dpsetting==-1|| - (unsigned short)(operand-dpsetting*256)>=256) - opsize=3; else opsize=2; - } - if(opsize==1)opsize=2; - if(mode==5){ - postbyte=0x8f; - opsize=3; - } else mode=opsize-1; - } - } - if (debug) fprintf(stderr,"DEBUG: scanoperands: mode=%d, error=%d, postbyte=%02X\n",mode,error,postbyte); - if(mode>=5) { - skipspace(); - postbyte|=0x10; - if(*srcptr!=']')error|=2;else srcptr++; - } - if(pass==2&&unknown)error|=4; -} - -unsigned char codebuf[128]; -int codeptr; /* byte offset within instruction */ -int suppress; /* 0=no suppress 1=until ENDIF 2=until ELSE 3=until ENDM */ -int ifcount; /* count of nested IFs within suppressed text */ - -unsigned char outmode; /* 0 is binary, 1 is s-records */ - -unsigned short hexaddr; -int hexcount; -unsigned char hexbuffer[16]; -unsigned int chksum; - -extern int os9crc(unsigned char c, int crcp); -int crc; - -void -reset_crc() -{ - crc = -1; -} - - -void -flushhex() -{ - int i; - if(hexcount){ - fprintf(objfile,"S1%02X%04X",(hexcount+3)&0xff,hexaddr&0xffff); - for(i=0;i<hexcount;i++)fprintf(objfile,"%02X",hexbuffer[i]); - chksum+=(hexaddr&0xff)+((hexaddr>>8)&0xff)+hexcount+3; - fprintf(objfile,"%02X\n",0xff-(chksum&0xff)); - hexaddr+=hexcount; - hexcount=0; - chksum=0; - } -} - -void -outhex(unsigned char x) -{ - if(hexcount==16)flushhex(); - hexbuffer[hexcount++]=x; - chksum+=x; -} - -void -outbuffer() -{ - int i; - for(i=0;i<codeptr;i++) { - crc = os9crc(codebuf[i],crc); - if(!outmode)fputc(codebuf[i],objfile);else outhex(codebuf[i]); - } -} - -char *errormsg[]={"Error in expression", - "Illegal addressing mode", - "Undefined label", - "Multiple definitions of label", - "Relative branch out of range", - "Missing label", - "","","","","","","","","", - "Illegal mnemonic" - }; - -void -report() -{ - int i; - fprintf(stderr,"File %s, line %d:%s\n",curname,lineno,srcline); - for(i=0;i<16;i++) { - if(error&1) { - fprintf(stderr,"%s\n",errormsg[i]); - if(pass==2&&listing)fprintf(listfile,"**** %s\n",errormsg[i]); - } - error>>=1; - } - error = 0; - errors++; -} - -void -outlist() -{ - int i; - fprintf(listfile,"%04X: ",oldlc); - for(i=0;i<codeptr&&i<MAXLISTBYTES;i++) - fprintf(listfile,"%02X",codebuf[i]); - for(;i<=MAXLISTBYTES;i++) - fprintf(listfile," "); - fprintf(listfile,"%s\n",srcline); - while(i<codeptr) { - fprintf(listfile,"%04X: ",oldlc + i); - for(int j=0;i<codeptr&&j<MAXLISTBYTES;j++) { - fprintf(listfile,"%02X",codebuf[i]); i++; - } - fprintf(listfile,"\n"); - } -} - -void -setlabel(struct symrecord * lp) -{ - while (prevlp) { - struct symrecord *l = prevlp; - prevlp = prevlp->next; - l->next = 0; - setlabel(l); - } - if(lp) { - if(lp->cat!=13&&lp->cat!=6) { - if(lp->cat!=2||lp->value!=loccounter) - lp->value=loccounter; // error|=8; - } else { - lp->cat=2; - lp->value=loccounter; - } - } -} - -void -putbyte(unsigned char b) -{ - codebuf[codeptr++]=b; -} - -void -putword(unsigned short w) -{ - codebuf[codeptr++]=w>>8; - codebuf[codeptr++]=w&0x0ff; -} - -void -doaddress() /* assemble the right addressing bytes for an instruction */ -{ - int offs; - switch(mode) { - case 0: if(opsize==2)putbyte(operand);else putword(operand);break; - case 1: putbyte(operand);break; - case 2: putword(operand);break; - case 3: case 5: putbyte(postbyte); - switch(opsize) { - case 2: putbyte(operand);break; - case 3: putword(operand); - } - break; - case 4: case 6: offs=(unsigned short)operand-loccounter-codeptr-2; - if(offs<-128||offs>=128||opsize==3||unknown||!certain) { - if((!unknown)&&opsize==2&&(offs<-128||offs>=128) ) { - error|=16; makelonger(glineno); - } - offs--; - opsize=3; - postbyte++; - } - putbyte(postbyte); - if (debug) fprintf(stderr,"DEBUG: doaddress: mode=%d, opsize=%d, error=%d, postbyte=%02X, operand=%04X offs=%d\n",mode,opsize,error,postbyte,operand,offs); - if(opsize==3)putword(offs); - else putbyte(offs); - } -} - -void -onebyte(int co) -{ - putbyte(co); -} - -void -twobyte(int co) -{ - putword(co); -} - -void -oneimm(int co) -{ - scanoperands(); - if(mode>=3) - error|=2; - putbyte(co); - putbyte(operand); -} - -void -lea(int co) -{ - putbyte(co); - scanoperands(); - if(mode==0) error|=2; - if(mode<3) { - opsize=3; - postbyte=0x8f; - mode=3; - } - if (debug) fprintf(stderr,"DEBUG: lea: mode=%d, opsize=%d, error=%d, postbyte=%02X, *src=%c\n",mode,opsize,error,postbyte,*srcptr); - doaddress(); -} - -void -sbranch(int co) -{ - int offs; - scanoperands(); - if(mode!=1&&mode!=2)error|=2; - offs=(unsigned short)operand-loccounter-2; - if(!unknown&&(offs<-128||offs>=128)) { - error|=16;makelonger(glineno); - if (co==0x20) { - if(mode!=1&&mode!=2)error|=2; - putbyte(0x16); - putword(operand-loccounter-3); - } else { - if(mode!=1&&mode!=2)error|=2; - putbyte(0x10); - putbyte(co); - putword(operand-loccounter-4); - } - return; - } - if(pass==2&&unknown)error|=4; - putbyte(co); - putbyte(offs); -} - -void -lbra(int co) -{ - scanoperands(); - if(mode!=1&&mode!=2)error|=2; - putbyte(co); - putword(operand-loccounter-3); -} - -void -lbranch(int co) -{ - scanoperands(); - if(mode!=1&&mode!=2)error|=2; - putword(co); - putword(operand-loccounter-4); -} - -void -arith(int co) -{ - scanoperands(); - switch(mode) { - case 0:opsize=2;putbyte(co);break; - case 1:putbyte(co+0x010);break; - case 2:putbyte(co+0x030);break; - default:putbyte(co+0x020); - } - doaddress(); -} - -void -darith(int co) -{ - scanoperands(); - switch(mode) { - case 0:opsize=3;putbyte(co);break; - case 1:putbyte(co+0x010);break; - case 2:putbyte(co+0x030);break; - default:putbyte(co+0x020); - } - doaddress(); -} - -void -d2arith(int co) -{ - scanoperands(); - switch(mode) { - case 0:opsize=3;putword(co);break; - case 1:putword(co+0x010);break; - case 2:putword(co+0x030);break; - default:putword(co+0x020); - } - doaddress(); -} - -void -oneaddr(int co) -{ - scanoperands(); - switch(mode) { - case 0: error|=2;break; - case 1: putbyte(co);break; - case 2: putbyte(co+0x70);break; - default: putbyte(co+0x60);break; - } - doaddress(); -} - -void -tfrexg(int co) -{ - struct regrecord * p; - putbyte(co); - skipspace(); - scanname(); - if((p=findreg(namebuf))==0)error|=2; - else postbyte=(p->tfr)<<4; - skipspace(); - if(*srcptr==',')srcptr++;else error|=2; - skipspace(); - scanname(); - if((p=findreg(namebuf))==0)error|=2; - else postbyte|=p->tfr; - putbyte(postbyte); -} - -void -pshpul(int co) -{ - struct regrecord *p; - putbyte(co); - postbyte=0; - do { - if(*srcptr==',')srcptr++; - skipspace(); - scanname(); - if((p=findreg(namebuf))==0)error|=2; - else postbyte|=p->psh; - skipspace(); - }while (*srcptr==','); - putbyte(postbyte); -} - -void -skipComma() -{ - while(*srcptr && *srcptr!='\n' && *srcptr!=',')srcptr++; - if (*srcptr==',') { - srcptr++; - } else { - error|=1; - } -} - -void os9begin() -{ - generate(); - os9=1; // contiguous code generation ( seprate rmb and code ) - oldlc = loccounter = rmbcounter = rmbmode = 0; - reset_crc(); - putword(0x87cd); - putword(scanexpr(0)-loccounter); // module size - if(unknown&&pass==2)error|=4; - skipComma(); - putword(scanexpr(0)-loccounter); // offset to module name - if(unknown&&pass==2)error|=4; - skipComma(); - putbyte(scanexpr(0)); // type / language - if(unknown&&pass==2)error|=4; - skipComma(); - putbyte(scanexpr(0)); // attribute - if(unknown&&pass==2)error|=4; - int parity=0; - for(int i=0; i< 8; i++) parity^=codebuf[i]; - putbyte(parity^0xff); // header parity - skipspace(); - while (*srcptr==',') { // there are some more - srcptr++; - putword(scanexpr(0)); - if(unknown&&pass==2)error|=4; - skipspace(); - } - prevloc = codeptr; - rmbmode = 1; // next org works on rmb - rmbcounter=0; - loccounter = 0x10000-codeptr; // should start at 0 -} - -void os9end() -{ - crc = crc ^ 0xffffff; - - putbyte((crc>>16)&0xff); - putbyte((crc>>8)&0xff); - putbyte(crc&0xff); - os9 = 0; -} - - -void -pseudoop(int co,struct symrecord * lp) -{ - int i; - char c; - char *fname; - int locsave; - - switch(co) { - case 0:/* RMB */ - // in OS9 mode, this generates no data - // loccounter will be reset after any code to the current code generation - if (os9 && !rmbmode) { - prevloc = loccounter; - oldlc = loccounter = rmbcounter; - rmbmode = 1; - } - setlabel(lp); - oldlc = loccounter; - operand=scanexpr(0); - if(unknown)error|=4; - loccounter+=operand; - if(generating&&pass==2) { - if(!outmode && !os9 ) { - for(i=0;i<operand;i++) { fputc(0,objfile); } - } else - flushhex(); - } - hexaddr=loccounter; - break; - case 5:/* EQU */ - operand=scanexpr(0); - if(!lp)error|=32; - else { - if(lp->cat==13||lp->cat==6|| - (lp->value==(unsigned short)operand&&pass==2)) { - if(exprcat==2)lp->cat=2; - else lp->cat=0; - lp->value=oldlc=operand; - } else // else error|=8; - lp->value=oldlc=operand; - } - break; - case 7:/* FCB */ - generate(); - setlabel(lp); - do { - if(*srcptr==',')srcptr++; - skipspace(); - if(*srcptr=='\"') { - srcptr++; - while(*srcptr!='\"'&&*srcptr) - putbyte(*srcptr++); - if(*srcptr=='\"')srcptr++; - } else { - putbyte(scanexpr(0)); - if(unknown&&pass==2)error|=4; - } - skipspace(); - } while(*srcptr==','); - break; - case 8:/* FCC */ - generate(); - setlabel(lp); - skipspace(); - c=*srcptr++; - while(*srcptr!=c&&*srcptr) - putbyte(*srcptr++); - if(*srcptr==c)srcptr++; - break; - case 9:/* FDB */ - generate(); - setlabel(lp); - do { - if(*srcptr==',')srcptr++; - skipspace(); - putword(scanexpr(0)); - if(unknown&&pass==2)error|=4; - skipspace(); - } while(*srcptr==','); - break; - case 23 :/* FCS */ - generate(); - setlabel(lp); - skipspace(); - int sep = *srcptr; - if(sep=='\"' || sep=='/' || sep=='\'') { - srcptr++; - while(*srcptr!=sep&&*srcptr) - putbyte(*srcptr++); - if(*srcptr==sep)srcptr++; - codebuf[codeptr-1] |= 0x80; // os9 string termination - } - break; - case 1: /* ELSE */ - suppress=1; - break; - case 21: /* IFP1 */ - if(pass==2)suppress=2; - break; - case 29: /* IFGT */ - operand=scanexpr(0); - if(operand<=0)suppress=2; - break; - case 31: /* IFLT */ - operand=scanexpr(0); - if(operand>=0)suppress=2; - break; - case 30: /* IFEQ */ - operand=scanexpr(0); - if(operand!=0)suppress=2; - break; - case 28: /* IFNE */ - case 10: /* IF */ - operand=scanexpr(0); - if(operand==0)suppress=2; - break; - case 33: /* IFNDEF */ - operand=scanexpr(0); - if(!unknown)suppress=2; - break; - case 12: /* ORG */ - operand=scanexpr(0); - if(unknown)error|=4; - if(generating&&pass==2&&!outmode&&!os9) { - for(i=0;i<(unsigned short)operand-loccounter;i++) - fputc(0,objfile); - } else flushhex(); - loccounter=operand; - hexaddr=loccounter; - break; - case 14: /* SETDP */ - operand=scanexpr(0); - if(unknown)error|=4; - if(!(operand&255))operand=(unsigned short)operand>>8; - if((unsigned)operand>255)operand=-1; - dpsetting=operand; - break; - case 15: /* SET */ - operand=scanexpr(0); - if(!lp)error|=32; - else { - if(lp->cat&1||lp->cat==6) { - if(exprcat==2)lp->cat=3; - else lp->cat=1; - lp->value=oldlc=operand; - } else // else error|=8; - lp->value=oldlc=operand; - } - break; - case 2: /* END */ - terminate=1; - break; - case 27: /* USE */ - case 16: /* INCLUDE */ - skipspace(); - if(*srcptr=='"')srcptr++; - i = 0; - for(i=0; !(srcptr[i]==0||srcptr[i]=='"'); i++); - int len = i; - fname = calloc(1,len); - for(i=0;i<len;i++) { - if(*srcptr==0||*srcptr=='"')break; - fname[i]=*srcptr++; - } - fname[i]=0; - processfile(fname); - codeptr=0; - srcline[0]=0; - break; - case 24: /* MOD */ - oldlc = loccounter = 0; - setlabel(lp); - os9begin(); - break; - case 25: /* EMOD */ - os9end(); - break; - case 32: /* OS9 */ - generate(); - setlabel(lp); - putword(0x103f); // SWI2 - putbyte(scanexpr(0)); - if(unknown&&pass==2)error|=4; - break; - case 18: /* TTL */ - break; - case 19: /* OPT */ - case 26: /* NAM */ - case 20: /* PAG */ - case 3: /* ENDIF/ENDC */ - break; - } -} - - -void -processline() -{ - struct symrecord * lp; - struct oprecord * op; - int co; - char c; - srcptr=srcline; - oldlc=loccounter; - // error=0; - unknown=0;certain=1; - lp=0; - codeptr=0; - if(isalnum(*srcptr)) { - scanname();lp=findsym(namebuf); - if(*srcptr==':') srcptr++; - if(lp && pass==2) { - oldlc = lp->value; - } - } - skipspace(); - if(isalnum(*srcptr)) { - scanname(); - op=findop(namebuf); - if(op) { - if(op->cat!=13){ - generate(); - setlabel(lp); - } - co=op->code; - switch(op->cat) { - case 0:onebyte(co);break; - case 1:twobyte(co);break; - case 2:oneimm(co);break; - case 3:lea(co);break; - case 4:sbranch(co);break; - case 5:lbranch(co);break; - case 6:lbra(co);break; - case 7:arith(co);break; - case 8:darith(co);break; - case 9:d2arith(co);break; - case 10:oneaddr(co);break; - case 11:tfrexg(co);break; - case 12:pshpul(co);break; - case 13:pseudoop(co,lp); - } - c=*srcptr; - if (debug) fprintf(stderr,"DEBUG: processline: mode=%d, opsize=%d, error=%d, postbyte=%02X c=%c\n",mode,opsize,error,postbyte,c); - if(c!=' '&&*(srcptr-1)!=' '&&c!=0&&c!=';')error|=2; - } - else error|=0x8000; - } else { - if (lp) { - lp->next = prevlp; - prevlp = lp; // os9 mode label can be data or code - } - } - if(pass==2) { - outbuffer(); - if(listing)outlist(); - } - if(error)report(); - loccounter+=codeptr; -} - -void -suppressline() -{ - struct oprecord * op; - srcptr=srcline; - oldlc=loccounter; - struct symrecord * lp = 0; - codeptr=0; - if(isalnum(*srcptr)) { - scanname();lp=findsym(namebuf); - if (lp) oldlc = lp->value; - if(*srcptr==':')srcptr++; - } - skipspace(); - scanname();op=findop(namebuf); - if(op && op->cat==13) { - if(op->code==10||op->code==13||op->code==29||op->code==28||op->code==21||op->code==30||op->code==31||op->code==33) ifcount++; - else if(op->code==3) { - if(ifcount>0)ifcount--;else if(suppress==1|suppress==2)suppress=0; - } else if(op->code==1) { - if(ifcount==0 && suppress==2)suppress=0; - } - } - if(pass==2&&listing)outlist(); } - -void -usage(char*nm) -{ - fprintf(stderr,"Usage: %s [-o objname] [-l listname] [-s srecord-file] srcname\n",nm); - exit(2); -} - -char * -strconcat(char *s,int spos,char *d) -{ - int slen = strlen(s); - int dlen = strlen(d); - if ( spos == 0) spos = slen; - char *out = calloc(1,spos+dlen+1); - int i = 0; - for(; i< spos; i++ ) out[i] = s[i]; - for(; i< spos+dlen+1; i++ ) out[i] = *d++; - return out; -} - - -void -getoptions(int c,char*v[]) -{ - int i=1; - if(c==1)usage(v[0]); - while(v[i]) { - if(strcmp(v[i],"-d")==0) { - debug=1; - i++; - } else if(strcmp(v[i],"-o")==0) { - objname = v[i+1]; - i+=2; - } else if(strcmp(v[i],"-s")==0) { - objname=v[i+1]; - outmode=1; - i+=2; - } else if(strcmp(v[i],"-l")==0) { - listname=v[i+1]; - i+=2; - } else if(strcmp(v[i],"-I")==0) { - struct incl *j = (struct incl *)malloc(sizeof(struct incl)); - j->name = v[i+1]; - j->next = 0; - if (!incls) incls = j; - else { - struct incl *k=incls ; - for(; k->next ; k = k->next ) ; - k->next = j; - } - i+=2; - } else if(*v[i]=='-') { - usage(v[0]); - } else { - if (srcname) usage(v[0]); - srcname=v[i]; - i++; - } - } - if(objname==0) { - for(i=0;srcname[i]!='.' && srcname[i]!=0 ;i++) ; - objname = strconcat(srcname,i,".b"); - } - listing=(listname!=0); -} - -void -expandline() -{ - int i=0,j=0,k,j1; - for(i=0;i<128&&j<128;i++) - { - if(inpline[i]=='\n') { - srcline[j]=0;break; - } - if(inpline[i]=='\t') { - j1=j; - for(k=0;k<8-j1%8 && j<128;k++)srcline[j++]=' '; - }else srcline[j++]=inpline[i]; - } - srcline[127]=0; -} - - -void -processfile(char *name) -{ - char *oldname; - int oldno; - FILE *srcfile; - oldname=curname; - curname=name; - oldno=lineno; - lineno=0; - if((srcfile=fopen(name,"r"))==0) { - int i = 0; - if (oldname) { - i = strlen(oldname); - while(i>0 && oldname[i]!='/') i--; - } - if (i>0) { - char *next = strconcat(oldname,i+1,name); - if((srcfile=fopen(next,"r"))!=0) { - curname = next; - } - } - if (!srcfile) { - for( struct incl *d = incls; d ; d = d->next) { - char *next = strconcat(d->name,0,name); - if((srcfile=fopen(next,"r"))!=0) { - curname = next; - break; - } - } - } - } - if (!srcfile) { - fprintf(stderr,"Cannot open source file %s\n",name); - exit(4); - } - while(!terminate&&fgets(inpline,128,srcfile)) { - expandline(); - lineno++; glineno++; - srcptr=srcline; - if(suppress) - suppressline(); - else - processline(); - } - setlabel(0); // process prevlp - fclose(srcfile); - if(suppress) { - fprintf(stderr,"improperly nested IF statements in %s",curname); - errors++; - suppress=0; - } - lineno=oldno; - curname=oldname; -} - -int -main(int argc,char *argv[]) -{ - char c; - getoptions(argc,argv); - pass=1; - errors=0; - generating=0; - terminate=0; - processfile(srcname); - if(errors) { - fprintf(stderr,"%d Pass 1 Errors, Continue?",errors); - c=getchar(); - if(c=='n'||c=='N') exit(3); - } - do { - pass=2; - prevloc = 0; - loccounter=0; - rmbcounter=0; - errors=0; - generating=0; - terminate=0; - glineno=0; - if(listing&&((listfile=fopen(listname,"w"))==0)) { - fprintf(stderr,"Cannot open list file"); - exit(4); - } - if((objfile=fopen(objname,outmode?"w":"wb"))==0) { - fprintf(stderr,"Cannot write object file\n"); - exit(4); - } - processfile(srcname); - fprintf(stderr,"%d Pass 2 errors.\n",errors); - if(listing) { - fprintf(listfile,"%d Pass 2 errors.\n",errors); - outsymtable(); - fclose(listfile); - } - if(outmode){ - flushhex(); - fprintf(objfile,"S9030000FC\n"); - } - fclose(objfile); - } while (longer()); - return 0; -} -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/basic/Makefile Mon Jul 23 16:07:12 2018 +0900 @@ -0,0 +1,52 @@ +# +# Makefile examples SBC09/Sim6809 +# +# created 1994 by L.C. Benschop +# 2014-06-25 - J.E. Klasek +# +# copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details. +# license: GNU General Public License version 2, see LICENSE for more details. +# + +ASM=../a09 + +PROGS=basic fbasic + +OTHER=floatnum.inc makeflot + + +all: $(ASM) $(PROGS) + +$(ASM): + $(MAKE) -c ../src a09 install + +# ------------------------------------ +# rules + +.SUFFIXES: .asm + +.asm: + $(ASM) -l $@.lst $< + +# ------------------------------------ + +basic: basic.asm + + +fbasic: fbasic.asm floatnum.inc + $(ASM) -l $@.lst fbasic.asm + +floatnum.inc: floatnum.src makeflot + ./makeflot < floatnum.src > floatnum.inc + +makeflot: makeflot.c + + +# ------------------------------------ + +cleanall: clean + rm -f $(PROGS) $(OTHER) + +clean: + rm -f core *.BAK *.lst $(PROGS) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/basic/README.txt Mon Jul 23 16:07:12 2018 +0900 @@ -0,0 +1,165 @@ +BASIC AND FLOATING POINT ROUTINES FOR THE 6809 +============================================== + +sbc09 stands for Lennart Benschop 6809 Single Board Computer. +It contains a assembler and simulator for the Motorola M6809 processor. + +copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details. +license: GNU General Public License version 2, see LICENSE for more details. + + + +FLOATING POINT ROUTINES FOR THE 6809 +------------------------------------ + +They are intended to be used with the sbc09 system. These routines +should be fairly portable to any 6809-based system. + +As it is an unfinished program (intended to become a full-featured +BASIC interpreter one day), I never released it before and I almost +forgot about it. Fortunately it was still on a backup CD-R that I +made in 2001. + + +FILES +- - - + +makeflot.c Conversion tool to convert floatnum.src to floatnum.inc + +floatnum.inc Floating point constants to be included in main program. +floatnum.src Same constants, but not converted to binary. + +fbasic.asm RPN calculator with floating point (just to test the FP routines. + This was intended to be part of a larger Basic interpreter, + but this was never finished). + +basic.asm Tiny Basic +basic.txt Tiny Basic instructions + +It was originally planned to turn this into a full-fledged BASIC +interpreter (maybe somewhat like BBC Basic), but this never +happened. It is now a rudimentary RPN calculator, just to test the +floating point routines. Each number or command needs to be on a separate +line. + + + + +MAKE THE PROGRAMS +- - - - - - - - - + +Simple: + +make + + +Or in single steps: + +compile the helper tool ... + +./makeflot <floatnum.src >floatnum.inc + + +assemble the FP calculator ... + +./a09 fbasic.asm + + +assemble Tiny Basic (integer only) ... + +./a09 basic.asm + + + + +RUN THE PROGRAMS +- - - - - - - - + + +Start the board simulator + +../v09 + +You should see the prompt "Welcome to BUGGY version 1.0" + +Type the command + +xl400 + +Press the escape character Control-] +(e.g. on Linux for a german style keyboard Control+AltGr+9) + +Then you see the v09> prompt. + +Type the command + +ufbasic + +Now the file "fbasic" will be uploaded to the board. + +Type the command + +g400 + +Now you can type floating point numbers and commands (RPN style), each +on a different line, like this + +2 +3 +* + 6.00000000E+00 + +1 +0 +/ + +The last calculation breaks back to the monitor. + +The following commands are available (see the source): ++ - * / (the normal arithmetic operators). += compare top two numbers on stack (and leave them), show < = or > +i round to integer (round to -Inf, like BASIC INT() function). +q square root +s sin +c cos +t tan +a atan +l ln +e exp +d duplicate number on stack +x exchange top numbers on stack. +r remove top of stack. + + + +IMPLEMENTATION NOTES +- - - - - - - - - - + +This is a 40-bit float, like many microcomputers of the 80s had, +including the Commodore 64, the ZX-Spectrum, the BBC and others. It +has an 8-bit exponent and a 32-bit mantissa (with hidden leading bit). +The basic operations (including square root) should be as accurate as +can be expected. + +It does not do IEEE-754 features, such as Infinity, NaN, +/-zero and +subnormal numbers, but appears to work quite reasonably. + +Trig functions deviate a few places in the 9th decimal. In particular +sin(pi/2) shows as 9.99999998E-01 instead of 1.00000000E+00. I +consider this acceptable and consistent with what could be expected. + +The Log function deviates a few places in the 8th decimal. LN(5) appears to +be about worst-case. I find this a bit disappointing. + +2 +l +5 +l ++ +e + +should show exactly 10, but it shows 9.99999970E+00 instead. This is +not caused by the exp function, but by the log of 5 (as I checked with +Python). + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/basic/basic.asm Mon Jul 23 16:07:12 2018 +0900 @@ -0,0 +1,1108 @@ + ;NAM TB01V137 +* WRITTEN 20-OCT-77 BY JOHN BYRNS +* REVISED 30-DEC-77 +* REVISED 18-JAN-78 +* REVISED 10-APR-78 +* REVISED 08-MAY-79 TO ELIMINATE USE OF SP +* REVISED 24-JAN-80 TO USE 6801 ON CHIP RAM +* REVISED 26-JAN-80 FOR NEW 6801 INSTRUCTIONS +* REVISED 24-JUL-81 FOR WHISTON BOARD +* REVISED 24-SEP-81 INCLUDE USER FUNCTION +* REVISED 08-APR-82 MAKE STANDALONE INCLUDE HEX CONSTANTS AND MEM FUNCTION +* REVISED 21-NOV-84 FOR 6809 +* REVISED FEB 94 ADAPTED TO SIMULATOR AND BUGFIXES BY L.C. BENSCHOP. +* +EOL EQU $04 +ETX EQU $03 +SPACE EQU $20 +CR EQU $0D +LF EQU $0A +BS EQU $08 +CAN EQU $18 +BELL EQU $07 +FILL EQU $00 +DEL EQU $7F +BSIZE EQU 73 +STKCUS EQU 48 +* +ACIA EQU $E000 +RMCR EQU ACIA +TRCS EQU ACIA +RECEV EQU ACIA+1 +TRANS EQU ACIA+1 +CNTL1 EQU $03 +CNTL2 EQU $15 +RDRF EQU $01 +ORFE EQU $20 +TDRE EQU $02 +* EDIT THE FOLLOWING EQUATES TO REFLECT THE +* DESIRED ROM AND RAM LAYOUT +LORAM EQU $0080 ADDRESS OF DIRECT PAGE SCRATCH RAM +BUFFER EQU $4000 ADDRESS OF MAIN RAM +RAMSIZ EQU $2000 SIZE OF MAIN RAM +ROMADR EQU $400 ADDRESS OF TINY BASIC ROM +* +RAMBEG EQU BUFFER+BSIZE +RAMEND EQU BUFFER+RAMSIZ +* +RAMPAT EQU $AA0F +ROMPAT EQU $F055 +* + ORG LORAM +USRBAS RMB 2 +USRTOP RMB 2 +STKLIM RMB 2 +STKTOP RMB 2 +CURSOR RMB 2 +SAVESP RMB 2 +LINENB RMB 2 +SCRTCH RMB 2 +CHAR RMB 2 +ZONE RMB 1 +MODE RMB 1 +RESRVD RMB 1 +LOEND EQU * +* + ORG ROMADR +BASIC JMP SETUP +WARMS LDS STKTOP + JSR INTEEE + BRA WMS05 +SETUP LDS #RAMEND-52 +SET03 STS STKTOP + JSR INTEEE +CLEAR LDD #RAMBEG + STD USRBAS + STD USRTOP +CLR02 STD STKLIM +WMS05 JSR CRLF + LDX #VSTR + JSR PUTSTR +CMDB LDS STKTOP + CLR MODE + JSR CRLF + LDX USRBAS + STX CURSOR +CMDE LDX #0000 + STX LINENB + TST MODE + BNE CMD01 + LDA #': + JSR PUTCHR +CMD01 JSR GETLIN + JSR TSTNBR + BCC CMD02 + BVS CMD05 + JSR SKIPSP + CMPA #EOL + BEQ CMDE + JSR MSLINE + BRA CMDB +CMD02 PSHS X + LDX USRTOP + CMPX STKLIM + PULS X + BEQ CMD03 + JMP ERRORR +CMD03 ADDD #0 + BEQ CMD05 +CMD04 PSHS D + SUBD #9999 + PULS D + BHI CMD05 + BSR EDITOR + BRA CMDE +CMD05 JMP ERRORS +VSTR FCC /TINY V1.37/ + FCB EOL +****************************** +****************************** +EDITOR PSHS D + JSR SKIPSP + STX SCRTCH + LDA 0,S + LDX CURSOR + CMPX USRTOP + BEQ ED00 + CMPD 0,X + BCC ED01 +ED00 LDX USRBAS +ED01 JSR FNDLIN + STX CURSOR + BCS ED04 + STX SAVESP + LEAX 2,X +ED02 LDA ,X+ + CMPA #EOL + BNE ED02 +ED03 CMPX USRTOP + BEQ ED35 + LDA ,X+ + STX CHAR + LDX SAVESP + STA ,X+ + STX SAVESP + LDX CHAR + BRA ED03 +ED35 LDX SAVESP + STX USRTOP + STX STKLIM +ED04 LDX SCRTCH + LDB #-1 +ED05 INCB + LDA ,X+ + CMPA #EOL + BNE ED05 + TSTB + BNE ED55 + LEAS 2,S + RTS +ED55 LEAX -1,X + ADDB #4 +ED06 LEAX -1,X + DECB + LDA 0,X + CMPA #SPACE + BEQ ED06 + LDA #EOL + STA 1,X + CLRA + LDX USRTOP + STX CHAR + ADDD USRTOP + STD USRTOP + STD STKLIM + JSR TSTSTK + BCC ED07 + STX USRTOP + STX STKLIM + JMP ERRORF +ED07 LDX USRTOP +ED08 STX SAVESP + LDX CHAR + CMPX CURSOR + BEQ ED09 + LDA ,-X + STX CHAR + LDX SAVESP + STA ,-X + BRA ED08 +ED09 PULS D + LDX CURSOR + STD ,X++ + STX CHAR +ED10 LDX SCRTCH + LDA ,X+ + STX SCRTCH + LDX CHAR + STA ,X+ + STX CHAR + CMPA #EOL + BNE ED10 + RTS +****************************** +****************************** +PUTS01 JSR PUTCHR + LEAX 1,X +PUTSTR LDA 0,X + CMPA #EOL + BNE PUTS01 + RTS +****************************** +****************************** +CRLF LDX #CRLFST + BSR PUTSTR + CLR ZONE + RTS +CRLFST FCB CR,LF,DEL,FILL,FILL,FILL,EOL +****************************** +****************************** +ERRORF BSR ER01 + FCC /SORRY/ + FCB EOL +ERRORS BSR ER01 + FCC /WHAT ?/ + FCB EOL +ERRORR BSR ER01 + FCC /HOW ?/ + FCB EOL +BREAK BSR ER01 + FCC /BREAK/ + FCB EOL +END BSR ER01 + FCC /STOP/ + FCB EOL +ER01 BSR CRLF + LDA #BELL + JSR PUTCHR + LDD LINENB + JSR PRNT4 + LDA #SPACE + JSR PUTCHR + PULS X + BSR PUTSTR + BSR CRLF + JMP CMDB +****************************** +****************************** +GL00 BSR CRLF +GETLIN LDX #BUFFER +GL03 JSR GETCHR + CMPA #SPACE + BCS GL05 + CMPA #$7F + BEQ GL03 + CMPX #BUFFER+BSIZE-1 + BNE GL04 + LDA #BELL + BRA GL02 +GL04 STA ,X+ +GL02 JSR PUTCHR + BRA GL03 +GL05 CMPA #BS + BEQ GL07 + CMPA #CAN + BEQ GL00 + CMPA #LF + BEQ GL09 + CMPA #CR + BNE GL03 + TST MODE + BEQ GL06 + JSR PUTCHR + BRA GL08 +GL06 PSHS X + JSR CRLF + PULS X +GL08 LDA #EOL + STA 0,X + LDX #BUFFER + RTS +GL07 CMPX #BUFFER + BEQ GL03 + LEAX -1,X + LDA #BS + JSR PUTCHR + LDA #SPACE + JSR PUTCHR + LDA #BS + BRA GL02 +GL09 ORCC #$01 + ROR MODE + BRA GL02 +****************************** +****************************** +REM00 LEAX 1,X +REM BSR SKIPSP + CMPA #EOL + BNE REM00 +ENDSMT JSR TSTEOL +ENDS02 LDA LINENB + ORA LINENB+1 + BEQ REM09 +REM05 CMPX USRTOP + BNE NXTLIN + JMP ERRORR +NXTLIN LDD ,X++ + STD LINENB +MSLINE JSR TSTBRK + BSR IFAN + BCS IMPLET + PSHS D +REM09 RTS +IMPLET JMP LET +****************************** +****************************** +IFAN BSR SKIPSP + STX CURSOR + LDX #VERBT +FAN00 LDA ,X+ + CMPA #EOL + BNE FAN04 + LDX CURSOR + ORCC #$01 + RTS +FAN04 STX CHAR + LDX CURSOR + STX SCRTCH +FAN05 LDX SCRTCH + CMPA 0,X + BNE FAN07 + LEAX 1,X + STX SCRTCH + LDX CHAR + LDA ,X+ + STX CHAR + CMPA #EOL + BNE FAN05 + LDD 0,X + LDX SCRTCH + ANDCC #$FE + RTS +FAN07 LDX CHAR +FAN08 LDA ,X+ + CMPA #EOL + BNE FAN08 + LEAX 2,X + BRA FAN00 +****************************** +****************************** +NXTNSP LEAX 1,X +SKIPSP LDA 0,X + CMPA #SPACE + BEQ NXTNSP + RTS +****************************** +****************************** +TSTHEX BSR TSTDIG + BCC TST05 + CMPA #'A + BCS TST03 + CMPA #'F + BHI TST03 + SUBA #'A-10 + ANDCC #$FE + RTS +****************************** +****************************** +TSTLTR CMPA #'A + BCS TST03 + CMPA #'Z + BLS TST05 +TST03 ORCC #$01 + RTS +****************************** +****************************** +TSTDIG CMPA #'0 + BCS TST03 + CMPA #'9 + BHI TST03 + SUBA #'0 +TST05 ANDCC #$FE + RTS +****************************** +****************************** +TSTVAR BSR SKIPSP + BSR TSTLTR + BCS TSTV03 + TFR A,B + LDA 1,X + BSR TSTLTR + BCC TST03 + LEAX 1,X + SUBB #'A + ASLB + CLRA + ADDD STKTOP +TSTV02 ANDCC #$FE +TSTV03 RTS +****************************** +****************************** +USER JSR ARGONE + PSHS D + JSR SKIPSP + CMPA #', + BEQ USER03 + CMPA #') + ORCC #$01 + BEQ USER05 +USER02 JMP ERRORS +USER03 LEAX 1,X + JSR EXPR + PSHS A + JSR SKIPSP + CMPA #') + PULS A + BNE USER02 + ANDCC #$FE +USER05 LEAX 1,X + STX CURSOR + JSR [,S++] + LDX CURSOR + ANDCC #$FE + RTS +****************************** +****************************** +TSTSNB JSR SKIPSP + CMPA #'- + BNE TSTNBR + LEAX 1,X + BSR TSTNBR + BCS TSN02 + NEGA + NEGB + SBCA #0 + ANDCC #$FC +TSN02 RTS +****************************** +****************************** +TSTNBR JSR SKIPSP + JSR TSTDIG + BCC TSTN02 + CMPA #'$ + ORCC #$01 + BNE TSTN09 +TSTN20 LEAX 1,X + CLR ,-S + CLR ,-S +TSTN23 LDA 0,X + JSR TSTHEX + BCS TSTN07 + LEAX 1,X + PSHS X + PSHS A + LDD 3,S + BITA #$F0 + BNE TSTN11 + ASLB + ROLA + ASLB + ROLA + ASLB + ROLA + ASLB + ROLA + ADDB ,S+ + STD 2,S + PULS X + BRA TSTN23 +TSTN02 LEAX 1,X + PSHS A + CLR ,-S +TSTN03 LDA 0,X + JSR TSTDIG + BCS TSTN07 + LEAX 1,X + PSHS X + PSHS A + LDD 3,S + ASLB + ROLA + BVS TSTN11 + ASLB + ROLA + BVS TSTN11 + ADDD 3,S + BVS TSTN11 + ASLB + ROLA + BVS TSTN11 + ADDB 0,S + ADCA #0 + BVS TSTN11 + STD 3,S + LEAS 1,S + PULS X + BRA TSTN03 +TSTN07 PULS D + ANDCC #$FE +TSTN09 ANDCC #$FD + RTS +TSTN11 LDX 1,S + LEAS 5,S + ORCC #$03 + RTS +****************************** +****************************** +TSTSTK STS SAVESP + LDD SAVESP + SUBD #STKCUS + SUBD STKLIM + RTS +****************************** +****************************** +PEEK JSR PAREXP + PSHS D + PSHS X + LDB [2,S] + PULS X + LEAS 2,S + CLRA + RTS +****************************** +****************************** +POKE JSR PAREXP + PSHS D + JSR SKIPSP + CMPA #'= + BEQ POKE05 + JMP ERRORS +POKE05 LEAX 1,X + JSR EXPR + JSR TSTEOL + PSHS X + STB [2,S] + PULS X + LEAS 2,S + JMP ENDS02 +****************************** +****************************** +TSTFUN JSR SKIPSP + STX CURSOR + LDX #FUNT + JSR FAN00 + BCS TSTF05 + PSHS D +TSTF05 RTS +****************************** +****************************** +FUNT FCC /USR/ + FCB EOL + FDB USER + FCC /PEEK/ + FCB EOL + FDB PEEK + FCC /MEM/ + FCB EOL + FDB TSTSTK + FCB EOL +****************************** +****************************** +FLINE LDX USRBAS +FNDLIN CMPX USRTOP + BNE FND03 + ORCC #$03 + RTS +FND03 CMPD 0,X + BNE FND05 + ANDCC #$FC + RTS +FND05 BCC FND07 + ORCC #$01 + ANDCC #$FD + RTS +FND07 PSHS A + LDA #EOL + LEAX 1,X +FND09 LEAX 1,X + CMPA 0,X + BNE FND09 + PULS A + LEAX 1,X + BRA FNDLIN +****************************** +****************************** +RELEXP BSR EXPR + PSHS D + CLRB + JSR SKIPSP + CMPA #'= + BEQ REL06 + CMPA #'< + BNE REL03 + LEAX 1,X + INCB + JSR SKIPSP + CMPA #'> + BNE REL05 + LEAX 1,X + ADDB #4 + BRA REL07 +REL03 CMPA #'> + BNE EXPR06 + LEAX 1,X + ADDB #4 + JSR SKIPSP +REL05 CMPA #'= + BNE REL07 +REL06 LEAX 1,X + ADDB #2 +REL07 PSHS B + BSR EXPR + PSHS X + SUBD 3,S + TFR CC,A + LSRA + TFR A,B + ASLA + ASLA + PSHS B + ADDA ,S+ + ANDA #$06 + BNE REL08 + INCA +REL08 CLRB + ANDA 2,S + BEQ REL09 + COMB +REL09 CLRA + PULS X + LEAS 3,S + RTS +****************************** +****************************** +EXPR CLR ,-S + CLR ,-S + JSR SKIPSP + CMPA #'- + BEQ EXPR05 + CMPA #'+ + BNE EXPR03 +EXPR02 LEAX 1,X +EXPR03 BSR TERM +EXPR04 ADDD 0,S + STD 0,S + JSR SKIPSP + CMPA #'+ + BEQ EXPR02 + CMPA #'- + BNE EXPR06 +EXPR05 LEAX 1,X + BSR TERM + NEGA + NEGB + SBCA #0 + BRA EXPR04 +EXPR06 PULS D + RTS +****************************** +****************************** +TERM JSR FACT + PSHS D +TERM03 JSR SKIPSP + CMPA #'* + BEQ TERM07 + CMPA #'/ + BEQ TERM05 + PULS D + RTS +TERM05 LEAX 1,X + BSR FACT + PSHS X + LEAX 2,S + PSHS D + EORA 0,X + JSR ABSX + LEAX 0,S + JSR ABSX + PSHS A + LDA #17 + PSHS A + CLRA + CLRB +DIV05 SUBD 2,S + BCC DIV07 + ADDD 2,S + ANDCC #$FE + BRA DIV09 +DIV07 ORCC #$01 +DIV09 ROL 7,S + ROL 6,S + ROLB + ROLA + DEC 0,S + BNE DIV05 + LDA 1,S + LEAS 4,S + TSTA + BPL TERM06 + LEAX 2,S + BSR NEGX +TERM06 PULS X + BRA TERM03 +TERM07 LEAX 1,X + BSR FACT +MULT PSHS B + LDB 2,S + MUL + LDA 1,S + STB 1,S + LDB 0,S + MUL + LDA 2,S + STB 2,S + PULS B + MUL + ADDA 0,S + ADDA 1,S + STD 0,S + BRA TERM03 +****************************** +****************************** +FACT JSR TSTVAR + BCS FACT03 + PSHS X + TFR D,X + LDD 0,X + PULS X +FACT02 RTS +FACT03 JSR TSTNBR + BCC FACT02 + JSR TSTFUN + BCC FACT02 +PAREXP BSR ARGONE + PSHS A + JSR SKIPSP + CMPA #') + PULS A + BNE FACT05 + LEAX 1,X + RTS +FACT05 JMP ERRORS +****************************** +****************************** +ARGONE JSR TSTSTK + BCC FACT04 + JMP ERRORF +FACT04 JSR SKIPSP + CMPA #'( + BNE FACT05 + LEAX 1,X + JMP EXPR +****************************** +****************************** +ABSX TST 0,X + BPL NEG05 +NEGX NEG 0,X + NEG 1,X + BCC NEG05 + DEC 0,X +NEG05 RTS +****************************** +****************************** +TSTEOL PSHS A + JSR SKIPSP + CMPA #EOL + BEQ TEOL03 + JMP ERRORS +TEOL03 LEAX 1,X + PULS A + RTS +****************************** +****************************** +LET JSR TSTVAR + BCC LET03 + JMP ERRORS +LET03 PSHS D + JSR SKIPSP + CMPA #'= + BEQ LET05 + JMP ERRORS +LET05 LEAX 1,X + JSR EXPR + BSR TSTEOL + STX CURSOR + PULS X + STD 0,X + LDX CURSOR + JMP ENDS02 +****************************** +****************************** +IF JSR RELEXP + TSTB + BEQ IF03 + JMP MSLINE +IF03 JMP REM +****************************** +****************************** +GOTO JSR EXPR + BSR TSTEOL + JSR FLINE + BCS GOSB04 + JMP NXTLIN +****************************** +****************************** +GOSUB JSR EXPR + BSR TSTEOL + STX CURSOR + JSR FLINE + BCC GOSB03 +GOSB04 JMP ERRORR +GOSB03 JSR TSTSTK + BCC GOSB05 + JMP ERRORF +GOSB05 LDD CURSOR + PSHS D + LDD LINENB + PSHS D + JSR NXTLIN + PULS D + STD LINENB + PULS X + JMP ENDS02 +****************************** +****************************** +RETURN EQU TSTEOL +****************************** +****************************** +PRINT JSR SKIPSP +PR01 CMPA #', + BEQ PR05 + CMPA #'; + BEQ PR07 + CMPA #EOL + BEQ PR04 + CMPA #'" + BNE PR02 + LEAX 1,X + BSR PRNTQS + BRA PR03 +PR02 JSR EXPR + PSHS X + BSR PRNTN + PULS X +PR03 JSR SKIPSP + CMPA #', + BEQ PR05 + CMPA #'; + BEQ PR07 + CMPA #EOL + BEQ PR04 + JMP ERRORS +PR04 PSHS X + JSR CRLF + PULS X + BRA PR08 +PR05 LDB #$7 +PR06 LDA #SPACE + JSR PUTCHR + BITB ZONE + BNE PR06 +PR07 LEAX 1,X + JSR SKIPSP + CMPA #EOL + BNE PR01 +PR08 LEAX 1,X + JMP ENDS02 +* +* +PRQ01 JSR PUTCHR +PRNTQS LDA ,X+ + CMPA #EOL + BNE PRQ03 + JMP ERRORS +PRQ03 CMPA #'" + BNE PRQ01 + RTS +* +PRNTN TSTA + BPL PRN03 + NEGA + NEGB + SBCA #0 + PSHS A + LDA #'- + JSR PUTCHR + PULS A +PRN03 LDX #PRNPT-2 +PRN05 LEAX 2,X + CMPD 0,X + BCC PRN07 + CMPX #PRNPTO + BNE PRN05 +PRN07 CLR CHAR +PRN09 CMPD 0,X + BCS PRN11 + SUBD 0,X + INC CHAR + BRA PRN09 +PRN11 PSHS A + LDA #'0 + ADDA CHAR + JSR PUTCHR + PULS A + CMPX #PRNPTO + BEQ PRN13 + LEAX 2,X + BRA PRN07 +PRN13 RTS +PRNPT FDB 10000 + FDB 1000 + FDB 100 + FDB 10 +PRNPTO FDB 1 +* +PRNT4 LDX #PRNPT+2 + BRA PRN07 +****************************** +****************************** +INPUT JSR TSTVAR + BCS IN11 + PSHS D + STX CURSOR +IN03 LDA #'? + JSR PUTCHR + JSR GETLIN +IN05 JSR SKIPSP + CMPA #EOL + BEQ IN03 + JSR TSTSNB + BCC IN07 + LDX #RMESS + JSR PUTSTR + JSR CRLF + BRA IN03 +IN07 STX SCRTCH + PULS X + STD 0,X + LDX CURSOR + JSR SKIPSP + CMPA #', + BEQ IN09 + JMP ENDSMT +IN09 LEAX 1,X + JSR TSTVAR + BCC IN13 +IN11 JMP ERRORS +IN13 PSHS D + PSHS X + LDX SCRTCH + JSR SKIPSP + CMPA #', + BNE IN05 + LEAX 1,X + BRA IN05 +RMESS FCC /RE-ENTER/ + FCB EOL +****************************** +****************************** +RUN LDX STKTOP + LDA #52 +RUN01 CLR ,X+ + DECA + BNE RUN01 + LDX USRBAS + JMP REM05 +****************************** +****************************** +LIST JSR TSTNBR + BCC LIST03 + CLRA + CLRB + STD CURSOR + LDA #$7F + BRA LIST07 +LIST03 STD CURSOR + JSR SKIPSP + CMPA #', + BEQ LIST05 + LDA CURSOR + BRA LIST07 +LIST05 LEAX 1,X + JSR TSTNBR + BCC LIST07 + JMP ERRORS +LIST07 JSR TSTEOL + PSHS D + LDD CURSOR + STX CURSOR + JSR FLINE +LIST09 CMPX USRTOP + BEQ LIST10 + PULS D + CMPD 0,X + BCS LIST11 + PSHS D + LDD ,X++ + PSHS X + JSR PRNT4 + PULS X + LDA #SPACE + JSR PUTCHR + JSR PUTSTR + LEAX 1,X + PSHS X + JSR CRLF + PULS X + JSR TSTBRK + BRA LIST09 +LIST10 LEAS 2,S + LDA #ETX + JSR PUTCHR +LIST11 LDX CURSOR + JMP ENDS02 +****************************** +****************************** +VERBT FCC /LET/ + FCB EOL + FDB LET + FCC /IF/ + FCB EOL + FDB IF + FCC /GOTO/ + FCB EOL + FDB GOTO + FCC /GOSUB/ + FCB EOL + FDB GOSUB + FCC /RETURN/ + FCB EOL + FDB RETURN + FCC /POKE/ + FCB EOL + FDB POKE + FCC /PRINT/ + FCB EOL + FDB PRINT + FCC /INPUT/ + FCB EOL + FDB INPUT + FCC /REM/ + FCB EOL + FDB REM + FCC /STOP/ + FCB EOL + FDB END + FCC /END/ + FCB EOL + FDB END + FCC /RUN/ + FCB EOL + FDB RUN + FCC /LIST/ + FCB EOL + FDB LIST + FCC /NEW/ + FCB EOL + FDB CLEAR + FCC /?/ + FCB EOL + FDB PRINT + FCB EOL +****************************** +****************************** +TSTBRK bsr BRKEEE + beq GETC05 +GETCHR bsr INEEE + CMPA #ETX + BNE GETC05 + JMP BREAK +GETC05 RTS +PUTCHR INC ZONE + JMP OUTEEE +****************************** +****************************** +INEEE BSR BRKEEE + BEQ INEEE + LDA RECEV + ANDA #$7F + RTS +OUTEEE PSHS A +OUT01 LDA TRCS + BITA #TDRE + BEQ OUT01 + PULS A + STA TRANS + RTS +BRKEEE PSHS A +BRK03 LDA TRCS + BITA #ORFE + BEQ BRK05 + LDA RECEV + BRA BRK03 +BRK05 BITA #RDRF + PULS A + RTS +* + LDA #CNTL1 + STA RMCR + LDA #CNTL2 + STA TRCS +INTEEE EQU * + RTS + + + +****************************** +****************************** + END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/basic/basic.txt Mon Jul 23 16:07:12 2018 +0900 @@ -0,0 +1,92 @@ + TINY BASIC SUMMARY + +Editing Standard Basic + +Direct Mode All Verbs Usable + +Statement Types + + PRINT Item List + LET Var = Expr (LET is optional) + IF Expr Relop Expr Statement + INPUT Variable List + GOTO Line Number + GOSUB Line Number + RETURN + POKE POKE(Expr) = Expr + STOP + LIST Line Number, Line Number (Line Numbers are optional) + RUN + NEW + +Functions + + USR Variable = USR(Expr,Expr) + PEEK Variable = PEEK(Expr) + MEM Variable = MEM + +Number Integers to _+32767 or Hex Integers preceded by a $ symbol + +Variable Letters A-Z + +Expression Variables, Numbers, and Functions combined with the following + operators +, -, *, /, (, ). + +Relop Comparison operators =, <, >, <=, >=, <>. + +Line Number Numbers 1 through 9999 + +String "ALPHANUMERICS" + +Item List Expressions and Strings seperated by format control + characters , and ;. + +Control Chars. Control H or "Back Space" deletes last input character. + Control X or "Cancel" deletes entire input line. + Control C Terminates Basic program or List operation and + returns control to command mode. + +Memory Usage Tiny Basic V1.37 + +$0080 - $009F Tiny Basic interpreter scratch area. +$00A0 - $00FD Not used by Tiny Basic interpreter. (usable USR routines) +$**** - $**** Pointer to Interrupt Vector Table. (Identical to LILBUG) +$D800 - $DFFF Input Buffer, Basic Program storage, Stack Space, and + Variables in RAM. +$**** - $**** Optional Power Up Basic Program and/or USR functions in ROM. +$E800 - $EFFF Tiny Basic interpreter ROM. + +$E800 Cold Start Address. +$E803 Warm Start Address. + + Tiny Basic USR Function + +The USR function in Tiny Basic takes 2 arguments and returns a value to a +variable. The form of the USR function is "LET V = USR(Expr,Expr)". +The USR function can be used in any expression in Tiny Basic as an example +"LET V = A * ( B + USR( $EF00, K))". The USR function can also be used with +the PRINT statement. + +The first argument of the USR function is evaluated to determine the address +or the machine language code to be called. The second argument is evaluated +and the value is send to the machine code routine in the D accumulator. The +second argument is optional, if it is present the Carry bit in the condition +code register will be cleared when the machine code routine is called. If the +second argument is not present the Carry Bit will be set when the machine code +is called. The machine code routine may return a result to the BASIC program +in the D accumulator, the value in the D accumulator on return from the machine +code routine will be used by the BASIC program as the value of the function. + +The machine code routine must execute a RTS instruction to return conterol to +the BASIC program. The machine code routine may use all the processor registers +freely and need not save and restore any registers. It is important that the +machine code routine not modify any memory used by the Tiny Basic interpreter. +Consult the memory map provided with your version of Tiny Basic to determine +which memory areas are not used. + +Tiny Basic handles interrupts with the same interrupt vectoring technique used +by LILBUG. Consult the LILBUG manual for details on interrupt vector usage. + + + + JPB 12-APR-82
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/basic/exampl.bas Mon Jul 23 16:07:12 2018 +0900 @@ -0,0 +1,18 @@ +10 REM SYRACUSE SEQUENCES. +20 PRINT "ENTER A POSITIVE NUMBER"; +30 INPUT K +40 IF K>0 GOTO 70 +50 PRINT "ERROR" +60 GOTO 20 +70 N=0 +80 PRINT K, +90 IF K=1 GOTO 160 +100 IF K<>2*(K/2) GOTO 130 +110 K=K/2 +120 GOTO 140 +130 K=3*K+1 +140 N=N+1 +150 GOTO 80 +160 PRINT +170 PRINT "CONVERGED TO 1 IN ";N;" STEPS." +180 END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/basic/fbasic.asm Mon Jul 23 16:07:12 2018 +0900 @@ -0,0 +1,1344 @@ + ;FBASIC, Floating point BASIC. + + ;This is not a BASIC interpreter, but a simple RPN calculator + ;to test the floating point routines. As such it is not a finished + ;application. + ;Written in 1996 by Lennart Benschoo. + ; + ;2014-07-26: Added welcome message, a few more comments. + + ;Configuration info, change this for different apps. +ROM equ 0 ;Flag to indicate that BASIC is in ROM +ROMSTART equ $8000 ;First ROM address. +RAMSTART equ $400 ;First RAM address. +RAMTOP equ $8000 ;Last RAM address +1. + +PROGORG equ ROM*ROMSTART+(1-ROM)*RAMSTART + + ;First the O.S. vectors in the zero page. + org $0000 +* First the I/O routine vectors. +getchar rmb 3 ;Jump to getchar routine. +putchar rmb 3 ;Jump to putchar routine. +getline rmb 3 ;Jump to getline routine. +putline rmb 3 ;Jump to putline routine. +putcr rmb 3 ;Jump to putcr routine. +getpoll rmb 3 ;Jump to getpoll routine. +xopenin rmb 3 ;Jump to xopenin routine. +xopenout rmb 3 ;Jump to xopenout routine. +xabortin rmb 3 ;Jump to xabortin routine. +xclosein rmb 3 ;Jump to xclosein routine. +xcloseout rmb 3 ;Jump to xcloseout routine. +delay rmb 3 ;Jump to delay routine. + +timer equ *+6 ;3-byte timer. +linebuf equ $200 ;Input line buffer +xerrvec equ $280+6*3 ;Error vector. + +* Now BASIC's own zero-page allocations. + org $40 +startprog rmb 2 ;Start of BASIC program. +endprog rmb 2 ;End of BASIC program. +endvar rmb 2 ;End of variable area. +fpsp rmb 2 ;Floating point stack pointer (grows up). +endmem rmb 2 + +intbuf rmb 4 ;Buffer to store integer. +intbuf2 rmb 4 +bcdbuf rmb 5 ;Buffer for BCD conversion. + +endstr rmb 2 ;End address of string. +dpl rmb 1 ;Decimal point location. + +* The BASIC interpreter starts here. + org PROGORG +cold jmp docold +warm bra noboot + +* Cold start routine. +docold ldx #RAMTOP + stx endmem + tfr x,s + ldu #FREEMEM + stu startprog + clr ,u+ + clr ,u+ + stu endprog + ldx PROGEND + leax 1,x + beq noboot ;Test for autoboot program. + ldx #PROGEND + stx startprog + jmp dorun +noboot jsr doclear + ;; Print a welcome message first. + ldx #nbmesg + ldb #nbmend-nbmesg + jsr putline + jsr putcr + ldd #$4000 + std fpsp + ldu fpsp + ;; Main loop. This is a simple RPN calculator that treat +nbloop ldx #$5000 + ldb #20 + jsr getline + clr b,x + cmpb #1 + lbne donum ; All commands are single-character, everything + ; else is treated as a number. Also the single-character lines that + ; are not commands are later parsed as numbers. + ldb ,x + cmpb #'+' ; Add + bne nb1 + jsr fpadd + lbra doprint +nb1 cmpb #'-' ; Subtract + bne nb2 + jsr fpsub + lbra doprint +nb2 cmpb #'*' ; Multiply + bne nb3 + jsr fpmul + lbra doprint +nb3 cmpb #'/' ; Divide + bne nb4 + jsr fpdiv + lbra doprint +nb4 cmpb #'q' ; Square root. + bne nb5 + jsr fpsqrt + lbra doprint +nb5 cmpb #'i' ; Round to -Inf INT() in BASIC. + bne nb6 + jsr fpfloor + lbra doprint +nb6 cmpb #'s' ; SIN() function + bne nb7 + jsr fpsin + lbra doprint +nb7 cmpb #'=' ; Compare top two numbers Show < = or > + bne nb8 + jsr fpcmp + beq nbeq + bcc nbgt + ldb #'<' + bra nbcmp +nbeq ldb #'=' + bra nbcmp +nbgt ldb #'>' +nbcmp leau -10,u + jsr putchar + jsr putcr + bra nbloop +nb8 cmpb #'c' ; COS() function. + bne nb9 + jsr fpcos + bra doprint +nb9 cmpb #'t' ; TAN() function. + bne nb10 + jsr fptan + bra doprint +nb10 cmpb #'a' ; ATAN() function. + bne nb11 + jsr fpatan + bra doprint +nb11 cmpb #'e' ; EXP() function. + bne nb12 + jsr fpexp + bra doprint +nb12 cmpb #'l' ; LN() function. + bne nb13 + jsr fln + bra doprint +nb13 cmpb #'d' ; Duplicate top number on stack. + bne nb14 + jsr fpdup + bra doprint ; Exchange top two numbers on stack. +nb14 cmpb #'x' + bne nb15 + jsr fpexg + bra doprint +nb15 cmpb #'r' ; Drop top from stack. + bne nb16 + leau -5,u + bra doprint +nb16 +donum ldy #$5000 + jsr scannum + lbra nbloop +doprint ldy #$5000 + jsr fpdup + jsr fpscient + ldx #$5000 + ldb ,x+ + jsr putline + jsr putcr + lbra nbloop +nbmesg fcc "Welcome to RPN calculator" +nbmend + +doclear rts +dorun swi +makefree rts + +* Floating point primitives. + +* U is the floating point stack pointer and points to the first free +* location. Each number occupies 5 bytes, +* Format: byte0: binary exponent $00-$FF $80 means number in range 1..2. +* byte1-byte4 binary fraction between 1.0 and 2.0, msb would +* always be set, but replaced by sign. +* Special case: all bytes zero, number=0. + +* Exchange top two numbers on stack. +fpexg ldx -2,u + ldd -7,u + stx -7,u + std -2,u + ldx -4,u + ldd -9,u + stx -9,u + std -4,u + lda -5,u + ldb -10,u + sta -10,u + stb -5,u + rts + +fpdup leax -5,u +* Load fp number from address X and push onto stack. +fplod ldd ,x++ + std ,u++ + ldd ,x++ + std ,u++ + lda ,x+ + sta ,u+ +fckmem tfr s,d + stu fpsp + subd fpsp + subd #40 + lbcs makefree ;Test for sufficient free space. + rts + +* Pop fp number from stack and store into address X. +fpsto lda -5,u + sta ,x+ + ldd -4,u + std ,x++ + ldd -2,u + std ,x++ + leau -5,u + rts + +* Compare magnitude (second-top). +fpcmpmag lda -10,u + cmpa -5,u ;Compare exponents. + bne cmpend + ldd -4,u + anda #$7F ;Eliminate sign bit. + std ,--s + ldd -9,u + anda #$7F ;Eliminate sign bit. + subd ,s++ ;Compare msb of mantissa. + bne cmpend + ldd -7,u + subd -2,u + bne cmpend +cmpend rts + +* Test a top number for 0. +fptest0 tst -5,u + bne cmpend + ldd -4,u + bne cmpend + ldd -2,u + rts + +* Floating point subtraction. +fpsub jsr fpneg + +* Floating point addition. +fpadd bsr fpcmpmag ;First compare magnitudes. + bcc fpadd1 + jsr fpexg ;Put the biggest one second. +fpadd1 bsr fptest0 + beq fpaddend ;Done if smallest number is 0. + lda -10,u + suba -5,u ;Determine exponent difference. + cmpa #32 + bhi fpaddend ;Done if difference too big. + ldb -9,u + andb #$80 + stb ,-s ;Store sign of biggest number. + eorb -4,u + stb ,-s ;Store difference of signs. + ldb -9,u + orb #$80 + stb -9,u + ldb -4,u + orb #$80 + stb -4,u ;Put the hidden msbs back in. + clr ,u ;Make extra mantissa byte. + tsta + beq fpadd2b ;Skip the alignment phase. +fpalign lsr -4,u + ror -3,u + ror -2,u + ror -1,u ;Shift the smaller number right to align + ror ,u + deca + bne fpalign +fpadd2b tst ,s+ + bmi dosub ;Did signs differ? Then subtract. + ldd -7,u ;Add the mantissas. + addd -2,u + std -7,u + ldd -9,u + adcb -3,u + adca -4,u + std -9,u + bcc fpadd2 +fpadd2a inc -10,u ;Sum overflowed, inc exp, shift mant. + lbeq fpovf ;If exponent overflowed, too bad. + ror -9,u + ror -8,u + ror -7,u + ror -6,u + ror ,u +fpadd2 tst ,u + bpl fpadd3 ;test msb of extra mantissa byte. + ldd -7,u ;Add 1 to mantissa if this is set + addd #1 + std -7,u + bcc fpadd3 + ldd -9,u + clr ,u + addd #1 + std -9,u + bcs fpadd2a +fpadd3 ldb -9,u + andb #$7F + eorb ,s+ + stb -9,u ;Put original sign back in. +fpaddend leau -5,u + rts +dosub ldb ,u + negb + stb ,u + ldd -7,u ;Signs differed, so sbutract. + sbcb -1,u + sbca -2,u + std -7,u + ldd -9,u + sbcb -3,u + sbca -4,u + std -9,u + bmi fpadd2 ;Number still normalized, then done. + ldd -9,u + bne fpnorm + ldd -7,u + bne fpnorm + tst ,u + beq fpundf ;If mantissa exactly zero, underflow. +fpnorm tst -10,u ;dec exp, shift mant left + beq fpundf ;Underflow, put a zero in. + dec -10,u + asl ,u + rol -6,u + rol -7,u + rol -8,u + rol -9,u + bpl fpnorm ;Until number is normalized. + bra fpadd2 + +fpundf clr -10,u ;Underflow, substitute zero. + clr -9,u + clr -8,u + clr -7,u + clr -6,u + leas 1,s ;Discard the sign on stack. + bra fpaddend + +* Compare Floating Point Numbers, flags as with unsigned comparison. +fpcmp lda -9,u + anda #$80 + sta ,-s + lda -4,u + anda #$80 + suba ,s+ ;Subtract the signs, subtraction is reversed. + bne fpcmpend + tst -9,u + bmi fpcmpneg ;Are numbers negative? + jmp fpcmpmag +fpcmpneg jsr fpcmpmag + beq fpcmpend + tfr cc,a + eora #$1 + tfr a,cc ;Reverse the carry flag. +fpcmpend rts + +* Multiply floating point numbers. +fpmul lda -9,u + eora -4,u + anda #$80 + sta ,-s ;Sign difference to stack. + jsr fptest0 ;Test one operand for 0 + beq fpundf + ldd -7,u + bne fpmula + ldd -9,u + bne fpmula ;And the other one. + ldb -10,u + beq fpundf +fpmula ldb -9,u + orb #$80 + stb -9,u + ldb -4,u + orb #$80 + stb -4,u ;Put hidden msb back in. + lda -10,u + suba #$80 ;Make unbiased signed num of exponents. + sta ,-s + lda -5,u + suba #$80 + adda ,s+ ;add exponents. + bvc fpmul1 ;Check over/underflow + lbmi fpovf + bra fpundf +fpmul1 adda #$80 ;Make exponent biased again. + sta -10,u ;Store result exponent. +* Now perform multiplication of mantissas to 40-bit product. +* 0,u--4,u product. 5,u--9,u added term +* Having a mul instruction is nice, but using it for an efficient +* multiprecision multiplicaton is hard. This routine has 13 mul instructions. + lda -1,u + ldb -8,u + mul ;b4*a2 + sta 4,u + lda -1,u + ldb -9,u + mul ;b4*a1 + addb 4,u + adca #0 + std 3,u + lda -2,u + ldb -7,u + mul ;b3*a3 + sta 9,u + lda -2,u + ldb -8,u + mul ;b3*a2 + addb 9,u + adca #0 + std 8,u + lda -2,u + ldb -9,u + mul ;b3*a1 + addb 8,u + adca #0 + std 7,u + ldd 8,u + addd 3,u + std 3,u + ldb 7,u + adcb #0 + stb 2,u ;Add b4*a and b3*a partial products. + lda -3,u + ldb -6,u + mul ;b2*a4 + sta 9,u + lda -3,u + ldb -7,u + mul ;b2*a3 + addb 9,u + adca #0 + std 8,u + lda -3,u + ldb -8,u + mul ;b2*a2 + addb 8,u + adca #0 + std 7,u + lda -3,u + ldb -9,u ;b2*a1 + mul + addb 7,u + adca #0 + std 6,u + ldd 8,u + addd 3,u + std 3,u + ldd 6,u + adcb 2,u + adca #0 + std 1,u ;Add b2*a partial product in. + lda -4,u + ldb -6,u + mul ;b1*a4 + std 8,u + lda -4,u + ldb -7,u + mul ;b1*a3 + addb 8,u + adca #0 + std 7,u + lda -4,u + ldb -8,u + mul ;b1*a2 + addb 7,u + adca #0 + std 6,u + lda -4,u + ldb -9,u + mul ;b1*a1 + addb 6,u + adca #0 + std 5,u + ldd 8,u + addd 3,u + std -6,u + ldd 6,u + adcb 2,u + adca 1,u + std -8,u + ldb 5,u + adcb #0 + stb -9,u ;Add product term b1*a in, result to dest. + bmi fpmul2 + asl -5,u + rol -6,u + rol -7,u + rol -8,u + rol -9,u ;Normalize by shifting mantissa left. + bra fpmul3 +fpmul2 inc -10,u ;increment exponent. + lbeq fpovf ;Test for overflow. +fpmul3 tst -5,u + lbpl fpadd3 + ldd -7,u ;Add 1 if msb of 5th nibble is set. + addd #1 + std -7,u + lbcc fpadd3 + ldd -9,u + addd #1 + std -9,u + bcs fpmul4 ;It could overflow. + lbra fpadd3 +fpmul4 clr -5,u + bra fpmul2 + +* Divide floating point numbers. +fpdiv lda -9,u + eora -4,u + anda #$80 + sta ,-s ;Sign difference to stack. + jsr fptest0 ;Test divisor for 0 + lbeq fpovf + ldd -7,u + bne fpdiva + ldd -9,u + bne fpdiva ;And the other one. + ldb -10,u + lbeq fpundf +fpdiva ldb -9,u + orb #$80 + stb -9,u + ldb -4,u + orb #$80 + stb -4,u ;Put hidden msb back in. + lda -5,u + suba #$80 ;Make unbiased signed difference of exponents. + sta ,-s + lda -10,u + suba #$80 + suba ,s+ ;subtract exponents. + bvc fpdiv1 ;Check over/underflow + lbmi fpovf + lbra fpundf +fpdiv1 adda #$80 ;Make exponent biased again. + sta -10,u ;Store result exponent. +* Now start the division of mantissas. Temprorary 34-bit quotient in 0,u--4,u +* -5,u is extra byte of dividend. + lda #34 + sta ,-s + clr ,u + clr 1,u + clr 2,u + clr 3,u + clr 4,u + clr -5,u +fpdivloop asl 4,u ;Shift quotient left. + rol 3,u + rol 2,u + rol 1,u + rol ,u + ldd -7,u ;Perform trial subtraction. + subd -2,u + std -7,u + ldd -9,u + sbcb -3,u + sbca -4,u + std -9,u + ldb -5,u + sbcb #0 + bcc fpdiv2 + ldd -7,u ;Undo the trial subtraction. + addd -2,u + std -7,u + ldd -9,u + adcb -3,u + adca -4,u + std -9,u + bra fpdiv4 +fpdiv2 stb -5,u ;Store new msb of quotient. + lda 4,u ;Add 1 to quotient. + adda #$40 + sta 4,u +fpdiv4 asl -6,u ;Shift dividend left. + rol -7,u + rol -8,u + rol -9,u + rol -5,u + dec ,s + bne fpdivloop + leas 1,s + ldd 3,u + std -6,u + ldd 1,u + std -8,u + ldb ,u + stb -9,u ;Move quotient to final location. + bmi fpdiv3 +fpdiv5 asl -5,u + rol -6,u + rol -7,u + rol -8,u + rol -9,u ;Normalize by shifting mantissa left. + ldb -10,u ;decrement exponent. + lbeq fpundf ;Test for underflow. + decb + stb -10,u +fpdiv3 tst -5,u + lbpl fpadd3 + ldd -7,u ;Add 1 if msb of 5th nibble is set. + addd #1 + std -7,u + lbcc fpadd3 + ldd -9,u + addd #1 + std -9,u + lbcs fpmul4 ;This addition could overflow. + lbra fpadd3 + +* Floating point negation. +fpneg jsr fptest0 + beq fpnegend ;Do nothing if number equals zero. + lda -4,u + eora #$80 + sta -4,u ;Invert the sign bit. +fpnegend rts + +* Convert unsigned double number at X to float. +ufloat leau 5,u ;Make room for extra number on stack. + ldd ,x + std -4,u + ldd 2,x + clr -5,u +uf16 std -2,u ;Transfer integer to FP number. + jsr fptest0 + beq ufzero + ldb #$9f ;Number is not zero. + stb -5,u + tst -4,u + bmi ufdone +ufloop dec -5,u ;Decrement exponent. + asl -1,u + rol -2,u + rol -3,u + rol -4,u ;Shift mantissa. + bpl ufloop ;until normalized. +ufdone ldb -4,u + andb #$7f + stb -4,u ;Remove the hidden msb. +ufend jmp fckmem ;Check that fp stack does not overflow +ufzero clr -5,u ;Make exponent zero as well. + bra ufend + +* Convert unsigned 16-bit integer in D to floating point. +unint2fp clr ,-s + bra i2fp2 +* Convert signed 16-bit integer in D to floating point. +int2fp sta ,-s ;Store sign byte. + bpl i2fp2 + comb + coma + addd #1 ;Negate D if negative. +i2fp2 leau 5,u + clr -4,u + clr -5,u + clr -3,u ;Clear msb + jsr uf16 + tst ,s+ + bmi fpneg + rts ;Negate number if it was negative. + +* Convert float to unsigned 32-bit integer at X. +* A is nonzero if number was not integer or zero. +uint ldd -4,u + ora #$80 ;Put the hidden msb back in. + std ,x + ldd -2,u + std 2,x ;Transfer mantissa. + clra + ldb -5,u + cmpb #$80 ;If less than 1, it's 0 + blo uizero + cmpb #$9f + lbhi intrange ;2^32 or higher, that's too bad. + beq uidone +uiloop lsr ,x + ror 1,x + ror 2,x + ror 3,x ;Adjust integer by shifting to right + adca #0 ;Add any shifted out bit into A. + incb + cmpb #$9f + blo uiloop +uidone leau -5,u + rts +uizero inca ; Indicate non-integer. + clr ,x ; Number is zero + clr 1,x + clr 2,x + clr 3,x + leau -5,u + rts + +* Convert fp number to signed or unsigned 16-bit number in D. +* Acceptable values are -65535..65535. +fp2uint ldb -5,u + stb ,-s ;Store sign. + ldx #intbuf + bsr uint + ldx ,x + lbne intrange ;Integer must be in 16-bit range. + ldd intbuf+2 + tst ,s+ + bpl fp2iend + comb + coma + addd #1 ;Negate number if negative. +fp2iend rts +* Convert fp number to signed 16-bit number in D. +fp2int ldb -5,u + stb ,-s ;Store sign of FP number. + bsr fp2uint + pshs d + eora ,s+ + lbmi intrange ;Compare sign to what it should be. + puls d,pc + +* Scan a number at address Y and convert to integer or floating point +scannum jsr skipspace + clr ,-s ;Store sign on stack. + cmpb #'-' ;Test for minus sign. + bne sn1 + inc ,s ;Set sign on stack + ldb ,y+ +sn1 jsr scanint ;First scan the number as an integer. + ldx #intbuf + jsr ufloat ;Convert to float. + ldb -1,y +sn1loop cmpb #'.' + bne sn1c + tst dpl ;If dpl already set, accept no other point. + bne sn1d + inc dpl + ldb ,y+ + bra sn1loop +sn1c subb #'0' + blo sn1d + cmpb #9 + bhi sn1d + clra + jsr int2fp ;Convert digit to fp + jsr fpexg + ldx #fpten + jsr fplod + jsr fpmul ;Multiply original number by 10. + jsr fpadd ;Add digit to it. + tst dpl + beq sn1k + inc dpl ;Adjust dpl (one more digit after .) +sn1k ldb ,y+ + bra sn1loop +sn1d tst ,s+ + beq sn1a + jsr fpneg ;Negate the number if negative. +sn1a clr ,-s + clr ,-s ;Prepare exponent part on stack. + ldb -1,y + cmpb #'e' + beq sn1e + cmpb #'E' + bne sn1f ;Test for exponent part. +sn1e ldb ,y+ + clr ,-s ;Prepare exponent sign on stack. + cmpb #'+' + beq sn1g + cmpb #'-' + bne sn1h + inc ,s ;Set sign to negative. +sn1g ldb ,y+ +sn1h lda dpl + pshs a + clr dpl + inc dpl + jsr scanint ;Scan the exponent part. + puls a + sta dpl ;Restore dpl. + lda intbuf + ora intbuf+1 + ora intbuf+2 + lbne fpovf ;Exponent may not be greater than 255. + ldb intbuf+3 + lbmi fpovf ;Not even greater than 127. + tst ,s+ + beq sn1i + negb +sn1i sex + std ,s +sn1f ldb dpl + beq sn1j + decb +sn1j negb + sex + addd ,s++ ;Add exponent part as well + pshs d + ldx #fpten + jsr fplod + puls d + jsr fpipower + jsr fpmul +sn1b rts + +* Scan integer number below 1e9 at address Y, first digit in B. +scanint clr dpl +scanint1 clr intbuf + clr intbuf+1 + clr intbuf+2 + clr intbuf+3 ;Initialize number +snloop cmpb #'.' + bne sn2a ;Test for decimal point. + tst dpl + bne sndone ;Done if second point found. + inc dpl ;Set dpl to indicate decimal point. + bra sn3 +sn2a subb #'0' + blo sndone + cmpb #9 + bhi sndone ;Check that character is a digit. + tst dpl + beq sn2b + inc dpl ;Incremend deecimal point loc if set. +sn2b pshs b + ldd intbuf+2 + aslb + rola + std intbuf+2 + std intbuf2+2 + ldd intbuf + rolb + rola + std intbuf + std intbuf2 + asl intbuf+3 + rol intbuf+2 + rol intbuf+1 + rol intbuf + asl intbuf+3 + rol intbuf+2 + rol intbuf+1 + rol intbuf + ldd intbuf+2 + addd intbuf2+2 + std intbuf +2 + ldd intbuf + adcb intbuf2+1 + adca intbuf2 + std intbuf ;Multiply the integer by 10 + ldd intbuf+2 + addb ,s+ ;Add the digit in. + adca #0 + std intbuf+2 + bcc sn2 + ldd intbuf + addd #1 + std intbuf +sn2 ldd intbuf + cmpd #$5f5 + blo sn3 + bhi snovf + ldd intbuf+2 ;note $5f5e100 is 100 million + cmpd #$e100 ;Compare result to 100 million + bhs snovf +sn3 ldb ,y+ ;get next digit. + bra snloop +snovf ldb ,y+ ;get next digit. +sndone ldb -1,y + rts + +*Convert integer at X to BCD. +int2bcd clr bcdbuf + clr bcdbuf+1 + clr bcdbuf+2 + clr bcdbuf+3 + clr bcdbuf+4 + ldb #4 +tstzero tst ,x+ + bne bcd1 + decb + bne tstzero ;Skip bytes that are zero. + bra sndone ;Done if number already zero. +bcd1 stb ,-s ;Store number of bytes. + leax -1,x +bcdloop ldb #8 +bcdloop1 rol ,x ;Get next bit of binary nunber + lda bcdbuf+4 + adca bcdbuf+4 + daa + sta bcdbuf+4 + lda bcdbuf+3 + adca bcdbuf+3 + daa + sta bcdbuf+3 + lda bcdbuf+2 + adca bcdbuf+2 + daa + sta bcdbuf+2 + lda bcdbuf+1 + adca bcdbuf+1 + daa + sta bcdbuf+1 + lda bcdbuf + adca bcdbuf + daa + sta bcdbuf ;Add BCD number to itself plus the extra bit. + decb + bne bcdloop1 + leax 1,x + dec ,s + bne bcdloop + leas 1,s ;Remove counter from stack. + rts + +* Raise fp number to an integer power contained in D. +fpipower sta ,-s ;Store sign of exponent. + bpl fppow1 ;Is exponent negative. + coma + comb + addd #1 ;Take absolute value of exponent. +fppow1 std ,--s ;Store the exponent. + ldx #fpone + jsr fplod ;Start with number one. +fppowloop lsr ,s + ror 1,s ;Divide exponent by 2. + bcc fppow2 ;Test if it was odd. + leax -10,u + jsr fplod + jsr fpmul ;Multiply result by factor. +fppow2 ldd ,s + beq fppowdone ;Is exponent zero? + leax -10,u + jsr fplod + jsr fpdup + jsr fpmul ;Sqaure the factor. + leax -15,u + jsr fpsto ;Store it in its place on stack. + bra fppowloop +fppowdone leas 2,s ;Remove exponent. + tst ,s+ + bpl fppow3 ;Was exponent negative? + ldx #fpone + jsr fplod + jsr fpexg + jsr fpdiv :compute 1/result. +fppow3 jsr fpexg + leau -5,u ;Remove factor from stack. + rts + + +* Convert fp number to string at address Y in scientific notation. +fpscient ldb #15 + stb ,y+ ;Store the string length. + lda #' ' + ldb -4,u + bpl fpsc1 + lda #'-' +fpsc1 sta ,y+ ;Store - or space depending on sign. + andb #$7f + stb -4,u ;Make number positive. + clr ,-s ;Store decimal exponent (default 0) + jsr fptest0 + beq fpsc2 ;Test for zero + lda -5,u + suba #$80 + suba #$1D ;Adjust exponent. + bvc fpsc11a + lda #-128 +fpsc11a sta ,-s ;store it to recover sign later. + bpl posexp + nega ;Take absolute value. +posexp ldb #5 + mul + lsra + rorb + lsra + rorb + lsra + rorb + lsra + rorb ;multiply by 5/16 approx 10log 2 + cmpb #37 + bls expmax + ldb #37 ;Maximum decimal exponent=37 +expmax tst ,s+ + bpl posexp1 + negb +posexp1 stb ,s ;Store approximate decimal exponent. + negb + sex ;Approximate (negated) decimal exponent in D. + pshs d + ldx #fpten + jsr fplod + puls d + jsr fpipower ;Take 10^-exp + jsr fpmul +fpsc1a ldx #fplolim + jsr fplod + jsr fpcmpmag ;Compare number to 100 million + leau -5,u + bhs fpsc1c + dec ,s ;Decrement approximate exponent. + ldx #fpten + jsr fplod + jsr fpmul ;Multiply by ten. + bra fpsc1a +fpsc1c ldx #fphilim + jsr fplod + jsr fpcmpmag ;Compare number to 1 billion + leau -5,u + blo fpsc1d + inc ,s ;Increment approximate exponent. + ldx #fpten + jsr fplod + jsr fpdiv ;Divide by ten. + bra fpsc1c +fpsc1d ldb ,s + addb #8 + stb ,s ;Adjust decimal exponent (8 decimals) + ldx #fphalf + jsr fplod + jsr fpadd ;Add 0.5 for the final round to integer. +* Number is either zero or between 100 million and 1 billion. +fpsc2 ldx #intbuf + jsr uint ;Convert decimal mantissa to integer. + jsr int2bcd ;Convert to bcd. + ldb bcdbuf + addb #'0' + stb ,y+ ;Store digit before decimal point + ldb #'.' + stb ,y+ ;Store decimal point. + lda #4 + sta ,-s + ldx #bcdbuf+1 +fpscloop lda ,x+ + tfr a,b + lsrb + lsrb + lsrb + lsrb + addb #'0' + stb ,y+ + anda #$0f + adda #'0 + sta ,y+ + dec ,s ;Convert the other 8 digits to ASCII + bne fpscloop + leas 1,s ;Remove loop counter. + ldb #'E' + stb ,y+ ;Store the E character. + lda #'+' + ldb ,s+ ;Get decimal exponent. + bpl fpsc3 ;Test sign of exponent. + lda #'-' + negb ;Take absolute value of exponent. +fpsc3 sta ,y+ ;Store sign of exponent. + stb intbuf+3 + clr intbuf+2 + clr intbuf+1 + clr intbuf + ldx #intbuf + jsr int2bcd ;Convert decimal exponent to bcd. + lda bcdbuf+4 + tfr a,b + lsrb + lsrb + lsrb + lsrb + addb #'0' + stb ,y+ ;Convert first exp digit to ascii + anda #$0f + adda #'0' + sta ,y+ ;And the second one. + rts + + + include "floatnum.inc" + +fpovf swi +intrange swi +inval swi + +* This routine takes the square root of an FP number. +* Uses Newton's algorithm. +fpsqrt tst -4,u + lbmi inval ;Negative arguments are invalid. + jsr fptest0 + beq sqdone ;Sqaure root of 0 is 0. + jsr fpdup + ldb -5,u + subb #$80 ;Unbias the exponent. + bpl sq1 + addb #1 +sq1 asrb ;Divide exponent by 2. + addb #$80 ;Make it biased again. + stb -5,u ;This is the initial guess for the root. + ldb #4 ;Do the loop 4 times. + stb ,-s +sqloop leax -10,u + jsr fplod + leax -10,u + jsr fplod + jsr fpdiv ;Divide argument by guess. + jsr fpadd ;Add to guess. + dec -5,u ;Divide this by two, giving new guess. + dec ,s + bne sqloop + leas 1,s + jsr fpexg + leau -5,u ;Remove argument, leave final guess. +sqdone rts + +* Compute the floor of an fp number (result is still fp. +fpfloor ldb -5,u + cmpb #$9f + bhs sqdone ;If abs value >=2^31, then already integer. + ldb -4,u + stb ,-s ;Stroe sign of number + andb #$7f + stb -4,u ;Take absolute value of number. + ldx #intbuf + jsr uint ;Convert to int (truncation) + sta ,-s ;Store number of fraction bits. + ldx #intbuf + jsr ufloat ;Convert back to float + ldd ,s++ + tstb + bpl sqdone + sta ,-s + jsr fpneg ;Negate number if it was negative + lda ,s+ + beq sqdone + ldx #fpone + jsr fplod + jmp fpsub ;Subtract 1 if negative & not integer. + +* Floating point modulo operation (floored modulo). +* Integer part of quotient is still left in intbuf +fpmod leax -10,u + jsr fplod + leax -10,u + jsr fplod + jsr fpdiv ;Perform division. + jsr fpfloor + jsr fpmul ;Multiply Quotient and Divisor + leax -10,u + jmp fpsub ;Dividend - quotient*divisor = modulus. + + +* Now the transcendental functions follow. +* They use approximation polynomials as defined in the +* Handbook of Mathematical Functions by Abramowitz & Stegun. + +* Compute polynomial, number of terms in B, coefficients start at Y +fppoly stb ,-s + ldx #fpzero + jsr fplod ;Start with zero. +polyloop leax ,y + jsr fplod + jsr fpadd ;Add next coefficient. + leay 5,y + leax -10,u + jsr fplod + jsr fpmul ;Multiply by x. + dec ,s + bne polyloop + leas 1,s + jsr fpexg + leau -5,u ;Remove x from stack. + rts + +add1 ldx #fpone + jsr fplod + jsr fpadd + rts + +halfpi ldx #fpi + jsr fplod + dec -5,u + rts + +* sin(x) +fpsin ldx #fpi + jsr fplod + inc -5,u ;Load 2*pi + jsr fpmod ;Modulo 2pi + bsr halfpi + jsr fpcmp ;Compare x to pi/2 + bls sin2 + inc -5,u ;Change pi/2 to pi + jsr fpsub + jsr fpneg ;x := pi-x if x>pi/2 + bsr halfpi + jsr fpneg + jsr fpcmp ;Compare x to -pi/2 + bhs sin2 + inc -5,u ;Change -pi/2 to -pi + jsr fpsub + jsr fpneg + bra sin3 +sin2 leau -5,u ;Drop the compare limit pi/2 or -pi/2 +sin3 jsr fpdup + jsr fpdup + jsr fpmul ;On stack: x, x*x + ldy #sincoeff + ldb #5 + jsr fppoly ;Do the sine polynomial with x*x as argument + jsr add1 ;Add 1 to the result. + jmp fpmul ;multiply the polynomial result with x. +* cos(x) +fpcos jsr halfpi + jsr fpsub + jsr fpneg + bra fpsin ;Compute sin(pi/2-x) + +* tan(x) +fptan jsr fpdup + jsr fpsin + jsr fpexg + jsr fpcos + jmp fpdiv ;Compute sin(x)/cos(x) + +* atan(x) +fpatan clr ,-s ;Make flag on stack + ldb -5,u + cmpb #$80 ;Compare magnitude to 1. + blo atn1 + inc ,s ;Set flag on stack. + ldx #fpone ;if x>1 then compute 1/x + jsr fplod + jsr fpexg + jsr fpdiv +atn1 jsr fpdup + jsr fpdup + jsr fpmul ;On stack: x, x*x + ldb #8 + ldy #atancoeff + jsr fppoly ;Doe the arctan polynomyal, x*x as argument. + jsr add1 ;Add 1 to result + jsr fpmul ;multiply result by x. + tst ,s+ + beq atndone + jsr halfpi + jsr fpsub + jsr fpneg ;Compute pi/2 - result when x was >1 +atndone rts + +* exp(x) +fpexp ldb -4,u + stb ,-s ;Store sign of x. + andb #$7f + stb -4,u ;Take absolute value. + ldx #fln2 + jsr fplod + jsr fpmod ;modulo ln2. + ldb #7 + ldy #expcoeff + jsr fppoly ;Do the exp(-x) polynomial. + jsr add1 + tst ,s+ + bpl exppos + ldb -5,u ;Number was negative. + subb intbuf+3 ;Subtract the integer quotient of the modln2 + bcs expund + lda intbuf + ora intbuf+1 + ora intbuf+2 + bne expund ;Underflow also if quotient >255 + stb -5,u ;Store exponent. + rts +exppos ldx #fpone + jsr fplod + jsr fpexg + jsr fpdiv ;x was postitive, compute 1/exp(-x) + ldb intbuf + orb intbuf+1 + orb intbuf+2 ;Check int part is less than 255 + lbne fpovf + ldb -5,u + addb intbuf+3 ;Add integer part to exponent. + lbcs fpovf ;Check for overflow. + stb -5,u + rts +expund leau -5,u + ldx #fpzero + jmp fplod ;underflow, result is zero. + +* ln(x) Natural logarithm +fln jsr fptest0 + lbeq inval ;Don't accept zero as argument. + tst -4,u + lbmi inval ;No negative numbers either. + ldb -5,u + stb ,-s ;Save the binary exponent. + ldb #$80 + stb -5,u ;Replace exponent with 1. + ldx #fpone ;Argument is now in range 1..2 + jsr fplod + jsr fpsub ;Subtract 1. + ldy #lncoeff + ldb #8 + jsr fppoly ;Do the ln(1+x) polynomial. + ldb ,s+ ;Get original exponent. + subb #$80 ;Unbias it. + sex + jsr int2fp ;Convert to fp. + ldx #fln2 + jsr fplod + jsr fpmul ;Multiply it by ln2. + jmp fpadd ;Add that to result. + +skipspace ldb ,y+ + cmpb #' ' + beq skipspace + rts + +PROGEND fdb $FFFF ;Indicate there is no AUTOBOOT app. + ;Flag can be overwritten by it. +FREEMEM equ ROM*RAMSTART+(1-ROM)*(PROGEND+2) + + + end +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/basic/floatnum.src Mon Jul 23 16:07:12 2018 +0900 @@ -0,0 +1,57 @@ +* Simple constants. +fpzero +0 +fpone +1 +fptwo +2 +fpten +10 +fphalf +0.5 +* Numbers used in conversion. +fplolim +99999999.95 +fphilim +999999999.5 +* Mathematical constants. +fpi +3.1415926535898 +fln2 +0.6931471805599 +* Even coefficients for the sin(x)/x polynumial. +sincoeff +-0.0000000239 + 0.0000027526 +-0.0001984090 + 0.0083333315 +-0.1666666664 +* Even coefficients for the arctan(x)/x polynomial. +atancoeff + 0.0028662257 +-0.0161657367 + 0.0429096138 +-0.0752896400 + 0.1065626393 +-0.1420889944 + 0.1999355085 +-0.3333314528 +* Coefficients for the exp(-x) polynomial. +expcoeff +-0.0001413161 + 0.0013298820 +-0.0083013598 + 0.0416573475 +-0.1666653019 + 0.4999999206 +-0.9999999995 +* Coefficients for the ln(1+x) polynomial. +lncoeff +-0.0064535442 + 0.0360884937 +-0.0953293897 + 0.1676540711 +-0.2407338084 + 0.3317990258 +-0.4998741238 + 0.9999964239
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/basic/makeflot.c Mon Jul 23 16:07:12 2018 +0900 @@ -0,0 +1,56 @@ +/* This program converts floating point numbers to + the 5-bit binary representation used in 6809 BASIC. +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include <ctype.h> +#include <string.h> + +main() +{ + double num; + char line[128],label[128]; + unsigned char byte[5]; + int expo,sign,i; + unsigned long mant; + label[0]=0; + printf("* These are the floating point constants.\n"); + printf("* They are generated by the program makeflot.c\n"); + while(fgets(line,128,stdin)) { + line[strlen(line)-1]=0; + if(!line[0])continue; + if(line[0]=='*'){printf("%s\n",line);continue;} + if(isalpha(line[0])) { + sscanf(line,"%s",label); + }else{ + sscanf(line,"%lf",&num); + if(num==0) { + sign=0; + expo=0; + mant=0; + }else{ + sign=0x80*(num<0); + num=fabs(num); + expo=0x9f; + while(num<2147483648.0){ + num=num*2; + expo-=1; + } + while(num>=4294967296.0){ + num=num/2; + expo+=1; + } + mant=num+0.5; + } + byte[0]=expo;byte[1]=((mant>>24)&0x7f)+sign; + byte[2]=((mant>>16)&0xff);byte[3]=((mant>>8)&0xff);byte[4]=mant&0xff; + printf("%-16s fcb $%02x,$%02x,$%02x,$%02x,$%02x ;%s\n", + label,byte[0],byte[1],byte[2],byte[3],byte[4],line); + label[0]=0; + } + } + printf("* End of floating point constants.\n"); + exit(0); +}
--- a/d09.c Mon Jul 23 10:52:33 2018 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1662 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> - - -/*************************************************************************** - Originally posted to comp.sys.m6809 by Didier Derny (didier@aida.remcomp.fr) - - Minor hacks by Alan DeKok - - Fixed: D_Indexed addressing used prog[2] and prog[3] when it meant - prog[pc+2] and prog[pc+3]: Would produce flawed disassemblies! - - changed addresses in D_Indexed to be all hex. - added 2 instances of 'extrabyte' in D_Indexed: would not skip them.. - Added PC offsets to D_Indexed ,PCR formats - added SWI2 print out as OS9 - - To do: - - handle command-line options properly... - - Fix handling of illegal opcodes so it doesn't skip a byte - i.e. $87 is a skip 2 - - Move defines to another file - - Add 6309 support - also add 6309 native-mode support, and listing of clock cycles for opcodes. - - Add OS-9 support - - add proper label-disassembly. i.e. 2-pass. - -****************************************************************************/ - -// extern int errno; -// extern char *sys_errlist[]; - -static unsigned char prog0[65536]; -unsigned char *prog = prog0; - -FILE *fp; - -typedef struct { - char *name; - int clock; - int bytes; - int (*display)(); - int (*execute)(); -} Opcode; - -typedef struct { - int address; - int length; - int width; -} String; - -int D_Illegal(Opcode *, int, int, char *); -int D_Direct(Opcode *, int, int, char *); -int D_Page10(Opcode *, int, int, char *); -int D_Page11(Opcode *, int, int, char *); -int D_Immediat(Opcode *, int, int, char *); -int D_ImmediatL(Opcode *, int, int, char *); -int D_Inherent(Opcode *, int, int, char *); -int D_Indexed(Opcode *, int, int, char *); -int D_Extended(Opcode *, int, int, char *); -int D_Relative(Opcode *, int, int, char *); -int D_RelativeL(Opcode *, int, int, char *); -int D_Register0(Opcode *, int, int, char *); -int D_Register1(Opcode *, int, int, char *); -int D_Register2(Opcode *, int, int, char *); -int D_Page10(Opcode *, int, int, char *); -int D_Page11(Opcode *, int, int, char *); -int D_OS9(Opcode *, int, int, char *); -char *IndexRegister(int); - -String stringtable[] = { - { 0xc321, 16, 16 }, - { 0xc395, 258, 16 }, - { 0xeb15, 50, 16 }, - { 0xee6f, 128, 16 }, - { 0xfdf4, 492, 16 }, - { 0xfff0, 16, 2 }, -}; - -int adoffset = 0; -int laststring = 6; - -Opcode optable[] = { - { "NEG ", 6, 2, D_Direct, NULL }, /* 0x00 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x01 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x02 */ - { "COM ", 6, 2, D_Direct, NULL }, /* 0x03 */ - { "LSR ", 6, 2, D_Direct, NULL }, /* 0x04 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x05 */ - { "ROR ", 6, 2, D_Direct, NULL }, /* 0x06 */ - { "ASR ", 6, 2, D_Direct, NULL }, /* 0x07 */ - { "LSL ", 6, 2, D_Direct, NULL }, /* 0x08 */ - { "ROR ", 6, 2, D_Direct, NULL }, /* 0x09 */ - { "DEC ", 6, 2, D_Direct, NULL }, /* 0x0a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x0b */ - { "INC ", 6, 2, D_Direct, NULL }, /* 0x0c */ - { "TST ", 6, 2, D_Direct, NULL }, /* 0x0d */ - { "JMP ", 3, 2, D_Direct, NULL }, /* 0x0e */ - { "CLR ", 6, 2, D_Direct, NULL }, /* 0x0f */ - - { "", 0, 1, D_Page10, NULL }, /* 0x10 */ - { "", 0, 1, D_Page11, NULL }, /* 0x11 */ - { "NOP ", 2, 1, D_Inherent, NULL }, /* 0x12 */ - { "SYNC ", 4, 1, D_Inherent, NULL }, /* 0x13 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x14 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x15 */ - { "LBRA ", 5, 3, D_RelativeL, NULL }, /* 0x16 */ - { "LBSR ", 9, 3, D_RelativeL, NULL }, /* 0x17 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x18 */ - { "DAA ", 2, 1, D_Inherent, NULL }, /* 0x19 */ - { "ORCC ", 3, 2, D_Immediat, NULL }, /* 0x1a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x1b */ - { "ANDCC", 3, 2, D_Immediat, NULL }, /* 0x1c */ - { "SEX ", 2, 1, D_Inherent, NULL }, /* 0x1d */ - { "EXG ", 8, 2, D_Register0, NULL }, /* 0x1e */ - { "TFR ", 6, 2, D_Register0, NULL }, /* 0x1f */ - - { "BRA ", 3, 2, D_Relative, NULL }, /* 0x20 */ - { "BRN ", 3, 2, D_Relative, NULL }, /* 0x21 */ - { "BHI ", 3, 2, D_Relative, NULL }, /* 0x22 */ - { "BLS ", 3, 2, D_Relative, NULL }, /* 0x23 */ - { "BCC ", 3, 2, D_Relative, NULL }, /* 0x24 */ - { "BCS ", 3, 2, D_Relative, NULL }, /* 0x25 */ - { "BNE ", 3, 2, D_Relative, NULL }, /* 0x26 */ - { "BEQ ", 3, 2, D_Relative, NULL }, /* 0x27 */ - { "BVC ", 3, 2, D_Relative, NULL }, /* 0x28 */ - { "BVS ", 3, 2, D_Relative, NULL }, /* 0x29 */ - { "BPL ", 3, 2, D_Relative, NULL }, /* 0x2a */ - { "BMI ", 3, 2, D_Relative, NULL }, /* 0x2b */ - { "BGE ", 3, 2, D_Relative, NULL }, /* 0x2c */ - { "BLT ", 3, 2, D_Relative, NULL }, /* 0x2d */ - { "BGT ", 3, 2, D_Relative, NULL }, /* 0x2e */ - { "BLE ", 3, 2, D_Relative, NULL }, /* 0x2f */ - - { "LEAX ", 4, 2, D_Indexed, NULL }, /* 0x30 */ - { "LEAY ", 4, 2, D_Indexed, NULL }, /* 0x31 */ - { "LEAS ", 4, 2, D_Indexed, NULL }, /* 0x32 */ - { "LEAU ", 4, 2, D_Indexed, NULL }, /* 0x33 */ - { "PSHS ", 5, 2, D_Register1, NULL }, /* 0x34 */ - { "PULS ", 5, 2, D_Register1, NULL }, /* 0x35 */ - { "PSHU ", 5, 2, D_Register2, NULL }, /* 0x36 */ - { "PULU ", 5, 2, D_Register2, NULL }, /* 0x37 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x38 */ - { "RTS ", 5, 1, D_Inherent, NULL }, /* 0x39 */ - { "ABX ", 3, 1, D_Inherent, NULL }, /* 0x3a */ - { "RTI ", 6, 1, D_Inherent, NULL }, /* 0x3b */ - { "CWAI ", 20, 2, D_Inherent, NULL }, /* 0x3c */ - { "MUL ", 11, 1, D_Inherent, NULL }, /* 0x3d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x3e */ - { "SWI ", 19, 1, D_Inherent, NULL }, /* 0x3f */ - - { "NEGA ", 2, 1, D_Inherent, NULL }, /* 0x40 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x41 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x42 */ - { "COMA ", 2, 1, D_Inherent, NULL }, /* 0x43 */ - { "LSRA ", 2, 1, D_Inherent, NULL }, /* 0x44 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x45 */ - { "RORA ", 2, 1, D_Inherent, NULL }, /* 0x46 */ - { "ASRA ", 2, 1, D_Inherent, NULL }, /* 0x47 */ - { "LSLA ", 2, 1, D_Inherent, NULL }, /* 0x48 */ - { "ROLA ", 2, 1, D_Inherent, NULL }, /* 0x49 */ - { "DECA ", 2, 1, D_Inherent, NULL }, /* 0x4a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x4b */ - { "INCA ", 2, 1, D_Inherent, NULL }, /* 0x4c */ - { "TSTA ", 2, 1, D_Inherent, NULL }, /* 0x4d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x4e */ - { "CLRA ", 2, 1, D_Inherent, NULL }, /* 0x4f */ - - { "NEGB ", 2, 1, D_Inherent, NULL }, /* 0x50 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x51 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x52 */ - { "COMB ", 2, 1, D_Inherent, NULL }, /* 0x53 */ - { "LSRB ", 2, 1, D_Inherent, NULL }, /* 0x54 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x55 */ - { "RORB ", 2, 1, D_Inherent, NULL }, /* 0x56 */ - { "ASRB ", 2, 1, D_Inherent, NULL }, /* 0x57 */ - { "LSLB ", 2, 1, D_Inherent, NULL }, /* 0x58 */ - { "ROLB ", 2, 1, D_Inherent, NULL }, /* 0x59 */ - { "DECB ", 2, 1, D_Inherent, NULL }, /* 0x5a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x5b */ - { "INCB ", 2, 1, D_Inherent, NULL }, /* 0x5c */ - { "TSTB ", 2, 1, D_Inherent, NULL }, /* 0x5d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x5e */ - { "CLRB ", 2, 1, D_Inherent, NULL }, /* 0x5f */ - - { "NEG ", 6, 2, D_Indexed, NULL }, /* 0x60 */ - { "?????", 0, 2, D_Illegal, NULL }, /* 0x61 */ - { "?????", 0, 2, D_Illegal, NULL }, /* 0x62 */ - { "COM ", 6, 2, D_Indexed, NULL }, /* 0x63 */ - { "LSR ", 6, 2, D_Indexed, NULL }, /* 0x64 */ - { "?????", 0, 2, D_Indexed, NULL }, /* 0x65 */ - { "ROR ", 6, 2, D_Indexed, NULL }, /* 0x66 */ - { "ASR ", 6, 2, D_Indexed, NULL }, /* 0x67 */ - { "LSL ", 6, 2, D_Indexed, NULL }, /* 0x68 */ - { "ROL ", 6, 2, D_Indexed, NULL }, /* 0x69 */ - { "DEC ", 6, 2, D_Indexed, NULL }, /* 0x6a */ - { "?????", 0, 2, D_Illegal, NULL }, /* 0x6b */ - { "INC ", 6, 2, D_Indexed, NULL }, /* 0x6c */ - { "TST ", 6, 2, D_Indexed, NULL }, /* 0x6d */ - { "JMP ", 3, 2, D_Indexed, NULL }, /* 0x6e */ - { "CLR ", 6, 2, D_Indexed, NULL }, /* 0x6f */ - - { "NEG ", 7, 3, D_Extended, NULL }, /* 0x70 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x71 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x72 */ - { "COM ", 7, 3, D_Extended, NULL }, /* 0x73 */ - { "LSR ", 7, 3, D_Extended, NULL }, /* 0x74 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x75 */ - { "ROR ", 7, 3, D_Extended, NULL }, /* 0x76 */ - { "ASR ", 7, 3, D_Extended, NULL }, /* 0x77 */ - { "LSL ", 7, 3, D_Extended, NULL }, /* 0x78 */ - { "ROL ", 7, 3, D_Extended, NULL }, /* 0x79 */ - { "DEC ", 7, 3, D_Extended, NULL }, /* 0x7a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x7b */ - { "INC ", 7, 3, D_Extended, NULL }, /* 0x7c */ - { "TST ", 7, 3, D_Extended, NULL }, /* 0x7d */ - { "JMP ", 4, 3, D_Extended, NULL }, /* 0x7e */ - { "CLR ", 7, 3, D_Extended, NULL }, /* 0x7f */ - - { "SUBA ", 2, 2, D_Immediat, NULL }, /* 0x80 */ - { "CMPA ", 2, 2, D_Immediat, NULL }, /* 0x81 */ - { "SBCA ", 2, 2, D_Immediat, NULL }, /* 0x82 */ - { "SUBD ", 4, 3, D_ImmediatL, NULL }, /* 0x83 */ - { "ANDA ", 2, 2, D_Immediat, NULL }, /* 0x84 */ - { "BITA ", 2, 2, D_Immediat, NULL }, /* 0x85 */ - { "LDA ", 2, 2, D_Immediat, NULL }, /* 0x86 */ - { "?????", 0, 2, D_Illegal, NULL }, /* 0x87 */ - { "EORA ", 2, 2, D_Immediat, NULL }, /* 0x88 */ - { "ADCA ", 2, 2, D_Immediat, NULL }, /* 0x89 */ - { "ORA ", 2, 2, D_Immediat, NULL }, /* 0x8a */ - { "ADDA ", 2, 2, D_Immediat, NULL }, /* 0x8b */ - { "CMPX ", 4, 3, D_ImmediatL, NULL }, /* 0x8c */ - { "BSR ", 7, 2, D_Relative, NULL }, /* 0x8d */ - { "LDX ", 3, 3, D_ImmediatL, NULL }, /* 0x8e */ - { "?????", 0, 2, D_Illegal, NULL }, /* 0x8f */ - - { "SUBA ", 4, 2, D_Direct, NULL }, /* 0x90 */ - { "CMPA ", 4, 2, D_Direct, NULL }, /* 0x91 */ - { "SBCA ", 4, 2, D_Direct, NULL }, /* 0x92 */ - { "SUBD ", 6, 2, D_Direct, NULL }, /* 0x93 */ - { "ANDA ", 4, 2, D_Direct, NULL }, /* 0x94 */ - { "BITA ", 4, 2, D_Direct, NULL }, /* 0x95 */ - { "LDA ", 4, 2, D_Direct, NULL }, /* 0x96 */ - { "STA ", 4, 2, D_Direct, NULL }, /* 0x97 */ - { "EORA ", 4, 2, D_Direct, NULL }, /* 0x98 */ - { "ADCA ", 4, 2, D_Direct, NULL }, /* 0x99 */ - { "ORA ", 4, 2, D_Direct, NULL }, /* 0x9a */ - { "ADDA ", 4, 2, D_Direct, NULL }, /* 0x9b */ - { "CMPX ", 6, 2, D_Direct, NULL }, /* 0x9c */ - { "JSR ", 7, 2, D_Direct, NULL }, /* 0x9d */ - { "LDX ", 5, 2, D_Direct, NULL }, /* 0x9e */ - { "STX ", 5, 2, D_Direct, NULL }, /* 0x9f */ - - { "SUBA ", 4, 2, D_Indexed, NULL }, /* 0xa0 */ - { "CMPA ", 4, 2, D_Indexed, NULL }, /* 0xa1 */ - { "SBCA ", 4, 2, D_Indexed, NULL }, /* 0xa2 */ - { "SUBD ", 6, 2, D_Indexed, NULL }, /* 0xa3 */ - { "ANDA ", 4, 2, D_Indexed, NULL }, /* 0xa4 */ - { "BITA ", 4, 2, D_Indexed, NULL }, /* 0xa5 */ - { "LDA ", 4, 2, D_Indexed, NULL }, /* 0xa6 */ - { "STA ", 4, 2, D_Indexed, NULL }, /* 0xa7 */ - { "EORA ", 4, 2, D_Indexed, NULL }, /* 0xa8 */ - { "ADCA ", 4, 2, D_Indexed, NULL }, /* 0xa9 */ - { "ORA ", 4, 2, D_Indexed, NULL }, /* 0xaa */ - { "ADDA ", 4, 2, D_Indexed, NULL }, /* 0xab */ - { "CMPX ", 6, 2, D_Indexed, NULL }, /* 0xac */ - { "JSR ", 7, 2, D_Indexed, NULL }, /* 0xad */ - { "LDX ", 5, 2, D_Indexed, NULL }, /* 0xae */ - { "STX ", 5, 2, D_Indexed, NULL }, /* 0xaf */ - - { "SUBA ", 5, 3, D_Extended, NULL }, /* 0xb0 */ - { "CMPA ", 5, 3, D_Extended, NULL }, /* 0xb1 */ - { "SBCA ", 5, 3, D_Extended, NULL }, /* 0xb2 */ - { "SUBD ", 7, 3, D_Extended, NULL }, /* 0xb3 */ - { "ANDA ", 5, 3, D_Extended, NULL }, /* 0xb4 */ - { "BITA ", 5, 3, D_Extended, NULL }, /* 0xb5 */ - { "LDA ", 5, 3, D_Extended, NULL }, /* 0xb6 */ - { "STA ", 5, 3, D_Extended, NULL }, /* 0xb7 */ - { "EORA ", 5, 3, D_Extended, NULL }, /* 0xb8 */ - { "ADCA ", 5, 3, D_Extended, NULL }, /* 0xb9 */ - { "ORA ", 5, 3, D_Extended, NULL }, /* 0xba */ - { "ADDA ", 5, 3, D_Extended, NULL }, /* 0xbb */ - { "CMPX ", 7, 3, D_Extended, NULL }, /* 0xbc */ - { "JSR ", 8, 3, D_Extended, NULL }, /* 0xbd */ - { "LDX ", 6, 3, D_Extended, NULL }, /* 0xbe */ - { "STX ", 6, 3, D_Extended, NULL }, /* 0xbf */ - - { "SUBB ", 2, 2, D_Immediat, NULL }, /* 0xc0 */ - { "CMPB ", 2, 2, D_Immediat, NULL }, /* 0xc1 */ - { "SBCB ", 2, 2, D_Immediat, NULL }, /* 0xc2 */ - { "ADDD ", 4, 3, D_ImmediatL, NULL }, /* 0xc3 */ - { "ANDB ", 2, 2, D_Immediat, NULL }, /* 0xc4 */ - { "BITB ", 2, 2, D_Immediat, NULL }, /* 0xc5 */ - { "LDB ", 2, 2, D_Immediat, NULL }, /* 0xc6 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc7 */ - { "EORB ", 2, 2, D_Immediat, NULL }, /* 0xc8 */ - { "ADCB ", 2, 2, D_Immediat, NULL }, /* 0xc9 */ - { "ORB ", 2, 2, D_Immediat, NULL }, /* 0xca */ - { "ADDB ", 2, 2, D_Immediat, NULL }, /* 0xcb */ - { "LDD ", 3, 3, D_ImmediatL, NULL }, /* 0xcc */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xcd */ - { "LDU ", 3, 3, D_ImmediatL, NULL }, /* 0xce */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xcf */ - - { "SUBB ", 4, 2, D_Direct, NULL }, /* 0xd0 */ - { "CMPB ", 4, 2, D_Direct, NULL }, /* 0xd1 */ - { "SBCB ", 4, 2, D_Direct, NULL }, /* 0xd2 */ - { "ADDD ", 6, 2, D_Direct, NULL }, /* 0xd3 */ - { "ANDB ", 4, 2, D_Direct, NULL }, /* 0xd4 */ - { "BITB ", 4, 2, D_Direct, NULL }, /* 0xd5 */ - { "LDB ", 4, 2, D_Direct, NULL }, /* 0xd6 */ - { "STB ", 4, 2, D_Direct, NULL }, /* 0xd7 */ - { "EORB ", 4, 2, D_Direct, NULL }, /* 0xd8 */ - { "ADCB ", 4, 2, D_Direct, NULL }, /* 0xd9 */ - { "ORB ", 4, 2, D_Direct, NULL }, /* 0xda */ - { "ADDB ", 4, 2, D_Direct, NULL }, /* 0xdb */ - { "LDD ", 5, 2, D_Direct, NULL }, /* 0xdc */ - { "STD ", 5, 2, D_Direct, NULL }, /* 0xdd */ - { "LDU ", 5, 2, D_Direct, NULL }, /* 0xde */ - { "STU ", 5, 2, D_Direct, NULL }, /* 0xdf */ - - { "SUBB ", 4, 2, D_Indexed, NULL }, /* 0xe0 */ - { "CMPB ", 4, 2, D_Indexed, NULL }, /* 0xe1 */ - { "SBCB ", 4, 2, D_Indexed, NULL }, /* 0xe2 */ - { "ADDD ", 6, 2, D_Indexed, NULL }, /* 0xe3 */ - { "ANDB ", 4, 2, D_Indexed, NULL }, /* 0xe4 */ - { "BITB ", 4, 2, D_Indexed, NULL }, /* 0xe5 */ - { "LDB ", 4, 2, D_Indexed, NULL }, /* 0xe6 */ - { "STB ", 4, 2, D_Indexed, NULL }, /* 0xe7 */ - { "EORB ", 4, 2, D_Indexed, NULL }, /* 0xe8 */ - { "ADCB ", 4, 2, D_Indexed, NULL }, /* 0xe9 */ - { "ORB ", 4, 2, D_Indexed, NULL }, /* 0xea */ - { "ADDB ", 4, 2, D_Indexed, NULL }, /* 0xeb */ - { "LDD ", 5, 2, D_Indexed, NULL }, /* 0xec */ - { "STD ", 5, 2, D_Indexed, NULL }, /* 0xed */ - { "LDU ", 5, 2, D_Indexed, NULL }, /* 0xee */ - { "STU ", 5, 2, D_Indexed, NULL }, /* 0xef */ - - { "SUBB ", 5, 3, D_Extended, NULL }, /* 0xf0 */ - { "CMPB ", 5, 3, D_Extended, NULL }, /* 0xf1 */ - { "SBCB ", 5, 3, D_Extended, NULL }, /* 0xf2 */ - { "ADDD ", 7, 3, D_Extended, NULL }, /* 0xf3 */ - { "ANDB ", 5, 3, D_Extended, NULL }, /* 0xf4 */ - { "BITB ", 5, 3, D_Extended, NULL }, /* 0xf5 */ - { "LDB ", 5, 3, D_Extended, NULL }, /* 0xf6 */ - { "STB ", 5, 3, D_Extended, NULL }, /* 0xf7 */ - { "EORB ", 5, 3, D_Extended, NULL }, /* 0xf8 */ - { "ADCB ", 5, 3, D_Extended, NULL }, /* 0xf9 */ - { "ORB ", 5, 3, D_Extended, NULL }, /* 0xfa */ - { "ADDB ", 5, 3, D_Extended, NULL }, /* 0xfb */ - { "LDD ", 6, 3, D_Extended, NULL }, /* 0xfc */ - { "STD ", 6, 3, D_Extended, NULL }, /* 0xfd */ - { "LDU ", 6, 3, D_Extended, NULL }, /* 0xfe */ - { "STU ", 6, 3, D_Extended, NULL }, /* 0xff */ -}; - -Opcode optable10[] = { - { "?????", 0, 1, D_Illegal, NULL }, /* 0x00 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x01 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x02 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x03 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x04 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x05 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x06 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x07 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x08 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x09 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x0a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x0b */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x0c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x0d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x0e */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x0f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x10 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x11 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x12 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x13 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x14 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x15 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x16 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x17 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x18 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x19 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x1a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x1b */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x1c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x1d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x1e */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x1f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x20 */ - { "LBRN ", 5, 4, D_RelativeL, NULL }, /* 0x21 */ - { "LBHI ", 5, 4, D_RelativeL, NULL }, /* 0x22 */ - { "LBLS ", 5, 4, D_RelativeL, NULL }, /* 0x23 */ - { "LBCC ", 5, 4, D_RelativeL, NULL }, /* 0x24 */ - { "LBCS ", 5, 4, D_RelativeL, NULL }, /* 0x25 */ - { "LBNE ", 5, 4, D_RelativeL, NULL }, /* 0x26 */ - { "LBEQ ", 5, 4, D_RelativeL, NULL }, /* 0x27 */ - { "LBVC ", 5, 4, D_RelativeL, NULL }, /* 0x28 */ - { "LBVS ", 5, 4, D_RelativeL, NULL }, /* 0x29 */ - { "LBPL ", 5, 4, D_RelativeL, NULL }, /* 0x2a */ - { "LBMI ", 5, 4, D_RelativeL, NULL }, /* 0x2b */ - { "LBGE ", 5, 4, D_RelativeL, NULL }, /* 0x2c */ - { "LBLT ", 5, 4, D_RelativeL, NULL }, /* 0x2d */ - { "LBGT ", 5, 4, D_RelativeL, NULL }, /* 0x2e */ - { "LBLE ", 5, 4, D_RelativeL, NULL }, /* 0x2f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x30 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x31 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x32 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x33 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x34 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x35 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x36 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x37 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x38 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x39 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x3a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x3b */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x3c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x3d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x3e */ -/* Fake SWI2 as an OS9 F$xxx system call */ - { "OS9 ", 20, 3, D_OS9, NULL }, /* 0x3f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x40 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x41 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x42 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x43 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x44 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x45 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x46 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x47 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x48 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x49 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x4a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x4b */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x4c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x4d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x4e */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x4f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x50 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x51 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x52 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x53 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x54 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x55 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x56 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x57 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x58 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x59 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x5a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x5b */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x5c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x5d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x5e */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x5f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x60 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x61 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x62 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x63 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x64 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x65 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x66 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x67 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x68 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x69 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x6a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x6b */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x6c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x6d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x6e */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x6f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x70 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x71 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x72 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x73 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x74 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x75 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x76 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x77 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x78 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x79 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x7a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x7b */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x7c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x7d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x7e */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x7f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x80 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x81 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x82 */ - { "CMPD ", 5, 4, D_ImmediatL, NULL }, /* 0x83 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x84 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x85 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x86 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x87 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x88 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x89 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x8a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x8b */ - { "CMPY ", 5, 4, D_ImmediatL, NULL }, /* 0x8c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x8d */ - { "LDY ", 4, 4, D_ImmediatL, NULL }, /* 0x8e */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x8f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x90 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x91 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x92 */ - { "CMPD ", 7, 3, D_Direct, NULL }, /* 0x93 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x94 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x95 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x96 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x97 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x98 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x99 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x9a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x9b */ - { "CMPY ", 7, 3, D_Direct, NULL }, /* 0x9c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x9d */ - { "LDY ", 6, 3, D_Direct, NULL }, /* 0x9e */ - { "STY ", 6, 3, D_Direct, NULL }, /* 0x9f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa0 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa1 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa2 */ - { "CMPD ", 7, 3, D_Indexed, NULL }, /* 0xa3 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa4 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa5 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa6 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa7 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa8 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa9 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xaa */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xab */ - { "CMPY ", 7, 3, D_Indexed, NULL }, /* 0xac */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xad */ - { "LDY ", 6, 3, D_Indexed, NULL }, /* 0xae */ - { "STY ", 6, 3, D_Indexed, NULL }, /* 0xaf */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb0 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb1 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb2 */ - { "CMPD ", 8, 4, D_Extended, NULL }, /* 0xb3 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb4 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb5 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb6 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb7 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb8 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb9 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xba */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xbb */ - { "CMPY ", 8, 4, D_Extended, NULL }, /* 0xbc */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xbd */ - { "LDY ", 7, 4, D_Extended, NULL }, /* 0xbe */ - { "STY ", 7, 4, D_Extended, NULL }, /* 0xbf */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc0 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc1 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc2 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc3 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc4 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc5 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc6 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc7 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc8 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc9 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xca */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xcb */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xcc */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xcd */ - { "LDS ", 4, 4, D_ImmediatL, NULL }, /* 0xce */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xcf */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd0 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd1 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd2 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd3 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd4 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd5 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd6 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd7 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd8 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd9 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xda */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xdb */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xdc */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xdd */ - { "LDS ", 6, 3, D_Direct, NULL }, /* 0xde */ - { "STS ", 6, 3, D_Direct, NULL }, /* 0xdf */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe0 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe1 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe2 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe3 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe4 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe5 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe6 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe7 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe8 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe9 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xea */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xeb */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xec */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xed */ - { "LDS ", 6, 3, D_Indexed, NULL }, /* 0xee */ - { "STS ", 6, 3, D_Indexed, NULL }, /* 0xef */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf0 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf1 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf2 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf3 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf4 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf5 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf6 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf7 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf8 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf9 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xfa */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xfb */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xfc */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xfd */ - { "LDS ", 7, 4, D_Extended, NULL }, /* 0xfe */ - { "STS ", 7, 4, D_Extended, NULL }, /* 0xff */ - -}; - - -Opcode optable11[] = { - { "?????", 0, 1, D_Illegal, NULL }, /* 0x00 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x01 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x02 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x03 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x04 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x05 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x06 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x07 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x08 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x09 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x0a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x0b */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x0c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x0d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x0e */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x0f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x10 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x11 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x12 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x13 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x14 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x15 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x16 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x17 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x18 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x19 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x1a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x1b */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x1c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x1d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x1e */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x1f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x20 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x21 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x22 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x23 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x24 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x25 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x26 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x27 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x28 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x29 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x2a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x2b */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x2c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x2d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x2e */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x2f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x30 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x31 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x32 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x33 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x34 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x35 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x36 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x37 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x38 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x39 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x3a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x3b */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x3c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x3d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x3e */ - { "SWI3 ", 20, 2, D_Inherent, NULL }, /* 0x3f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x40 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x41 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x42 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x43 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x44 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x45 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x46 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x47 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x48 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x49 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x4a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x4b */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x4c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x4d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x4e */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x4f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x50 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x51 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x52 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x53 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x54 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x55 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x56 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x57 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x58 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x59 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x5a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x5b */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x5c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x5d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x5e */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x5f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x60 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x61 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x62 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x63 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x64 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x65 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x66 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x67 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x68 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x69 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x6a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x6b */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x6c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x6d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x6e */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x6f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x70 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x71 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x72 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x73 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x74 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x75 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x76 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x77 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x78 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x79 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x7a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x7b */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x7c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x7d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x7e */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x7f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x80 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x81 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x82 */ - { "CMPU ", 5, 4, D_ImmediatL, NULL }, /* 0x83 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x84 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x85 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x86 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x87 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x88 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x89 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x8a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x8b */ - { "CMPS ", 5, 4, D_ImmediatL, NULL }, /* 0x8c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x8d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x8e */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x8f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0x90 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x91 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x92 */ - { "CMPU ", 7, 3, D_Direct, NULL }, /* 0x93 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x94 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x95 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x96 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x97 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x98 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x99 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x9a */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x9b */ - { "CMPS ", 7, 3, D_Direct, NULL }, /* 0x9c */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x9d */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x9e */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0x9f */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa0 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa1 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa2 */ - { "CMPU ", 7, 3, D_Indexed, NULL }, /* 0xa3 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa4 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa5 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa6 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa7 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa8 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xa9 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xaa */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xab */ - { "CMPS ", 7, 3, D_Indexed, NULL }, /* 0xac */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xad */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xae */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xaf */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb0 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb1 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb2 */ - { "CMPU ", 8, 4, D_Extended, NULL }, /* 0xb3 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb4 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb5 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb6 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb7 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb8 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xb9 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xba */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xbb */ - { "CMPS ", 8, 4, D_Extended, NULL }, /* 0xbc */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xbd */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xbe */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xbf */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc0 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc1 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc2 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc3 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc4 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc5 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc6 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc7 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc8 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xc9 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xca */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xcb */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xcc */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xcd */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xce */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xcf */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd0 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd1 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd2 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd3 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd4 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd5 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd6 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd7 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd8 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xd9 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xda */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xdb */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xdc */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xdd */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xde */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xdf */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe0 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe1 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe2 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe3 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe4 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe5 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe6 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe7 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe8 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xe9 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xea */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xeb */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xec */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xed */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xee */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xef */ - - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf0 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf1 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf2 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf3 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf4 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf5 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf6 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf7 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf8 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xf9 */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xfa */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xfb */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xfc */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xfd */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xfe */ - { "?????", 0, 1, D_Illegal, NULL }, /* 0xff */ -}; - - -struct os9syscall { int code; char *name; } os9sys[] = { - {0x0000,"F$LINK"}, - {0x0001,"F$LOAD"}, - {0x0002,"F$UNLINK"}, - {0x0003,"F$FORK"}, - {0x0004,"F$WAIT"}, - {0x0005,"F$CHAIN"}, - {0x0006,"F$EXIT"}, - {0x0007,"F$MEM"}, - {0x0008,"F$SEND"}, - {0x0009,"F$ICPT"}, - {0x000a,"F$SLEEP"}, - {0x000b,"F$SSPD"}, - {0x000c,"F$ID"}, - {0x000d,"F$SPRIOR"}, - {0x000e,"F$SSWI"}, - {0x000f,"F$PERR"}, - {0x0010,"F$PRSNAM"}, - {0x0011,"F$CMPNAM"}, - {0x0012,"F$SCHBIT"}, - {0x0013,"F$ALLBIT"}, - {0x0014,"F$DELBIT"}, - {0x0015,"F$TIME"}, - {0x0016,"F$STIME"}, - {0x0017,"F$CRC"}, - {0x0018,"F$GPRDSC"}, - {0x0019,"F$GBLKMP"}, - {0x001a,"F$GMODDR"}, - {0x001b,"F$CPYMEM"}, - {0x001c,"F$SUSER"}, - {0x001d,"F$UNLOAD"}, - {0x0027,"F$VIRQ"}, - {0x0028,"F$SRQMEM"}, - {0x0029,"F$SRTMEM"}, - {0x002a,"F$IRQ"}, - {0x002b,"F$IOQU"}, - {0x002c,"F$APROC"}, - {0x002d,"F$NPROC"}, - {0x002e,"F$VMODUL"}, - {0x002f,"F$FIND64"}, - {0x0030,"F$ALL64"}, - {0x0031,"F$RET64"}, - {0x0032,"F$SSVC"}, - {0x0033,"F$IODEL"}, - {0x0034,"F$SLINK"}, - {0x0035,"F$BOOT"}, - {0x0036,"F$BTMEM"}, - {0x0037,"F$GPROCP"}, - {0x0038,"F$MOVE"}, - {0x0039,"F$ALLRAM"}, - {0x003a,"F$ALLIMG"}, - {0x003b,"F$DELIMG"}, - {0x003c,"F$SETIMG"}, - {0x003d,"F$FREELB"}, - {0x003e,"F$FREEHB"}, - {0x003f,"F$ALLTSK"}, - {0x0040,"F$DELTSK"}, - {0x0041,"F$SETTSK"}, - {0x0042,"F$RESTSK"}, - {0x0043,"F$RELTSK"}, - {0x0044,"F$DATLOG"}, - {0x0045,"F$DATTMP"}, - {0x0046,"F$LDAXY"}, - {0x0047,"F$LDAXYP"}, - {0x0048,"F$LDDDXY"}, - {0x0049,"F$LDABX"}, - {0x004a,"F$STABX"}, - {0x004b,"F$ALLPRC"}, - {0x004c,"F$DELPRC"}, - {0x004d,"F$ELINK"}, - {0x004e,"F$FMODUL"}, - {0x004f,"F$MAPBLK"}, - {0x0050,"F$CLRBLK"}, - {0x0051,"F$DELRAM"}, - {0x0052,"F$GCMDIR"}, - {0x0053,"F$ALHRAM"}, - {0x0080 , "I$ATTACH"}, - {0x0081, "I$DETACH"}, - {0x0082 , "I$DUP"}, - {0x0083 , "I$CREATE"}, - {0x0084, "I$OPEN"}, - {0x0085 , "I$MAKDIR"}, - {0x0086 , "I$CHGDIR"}, - {0x0087 , "I$DELETE"}, - {0x0088, "I$SEEK"}, - {0x0089 , "I$READ"}, - {0x008a, "I$WRITE"}, - {0x008b , "I$READLN"}, - {0x008c , "I$WRITLN"}, - {0x008d, "I$GETSTT"}, - {0x008e , "I$SSTT"}, - {0x008f , "I$CLOSE"}, - {0x0090 , "I$DELETX"}, - } ; - - -int iotable[32] = { - 0x0000, - 0x0001, - 0x0002, - 0x0003, - 0x0008, - 0x0009, - 0x000a, - 0x000b, - 0x000c, - 0x000d, - 0x000e, - 0x0010, - 0x0011, - 0x0012, - 0x0013, - 0x0014, - 0x8000, - 0x8001, - 0x8002, - 0x8003, - 0x8004, - 0x8005, - 0x8006, - 0x8007, - 0x8008, - 0x8009, - 0x800a, - 0x800b, - 0x800c, - 0x800d, - 0x800e, - 0x800f, -}; - -char *iocomment[32] = { - "Data direction register port 1", - "Data direction register port 2", - "I/O register port 1", - "I/O register port 2", - "Timer control and status", - "Counter high byte", - "Counter low byte", - "Output compare high byte", - "Output compare low byte", - "Input capture high byte", - "Input capture low byte", - "Serial rate and mode register", - "Serial control and status register", - "Serial receiver data register", - "Serial transmit data register", - "Ram control register", - "Modem port 0", - "Modem port 1", - "Modem port 2", - "Modem port 3", - "Modem port 4", - "Modem port 5", - "Modem port 6", - "Modem port 7", - "Modem port 8", - "Modem port 9", - "Modem port 10", - "Modem port 11", - "Modem port 12", - "Modem port 13", - "Modem port 14", - "Modem port 15", -}; - -char *Inter_Register[16]={"D","X","Y","U","S","PC","??","??","A","B","CC","DP","??","??","??","??"}; - -char *Indexed_Register[4]={"X","Y","U","S"}; - -int lastio = 32; - -#pragma argsused -int D_Illegal(op, code, pc, suffix) -Opcode *op; -int code; -int pc; -char *suffix; -{ - fprintf(fp,"%0.2X %s%s", code, suffix, op->name); - return op->bytes; -} - -#pragma argsused -int D_Direct(op, code, pc, suffix) -Opcode *op; -int code; -int pc; -char *suffix; -{ - int offset; - - offset = prog[pc+1]; - fprintf(fp,"%0.2X %0.2X %s%s <$%0.2X", - code, offset, suffix, op->name, offset); - return op->bytes; -} - -#pragma argsused -int D_Page10(op, code, pc, suffix) -Opcode *op; -int code; -int pc; -char *suffix; -{ - fprintf(fp,"10 "); - code = prog[pc+1]; - return (*optable10[code].display)(&optable10[code], code, pc+1, ""); -} - -#pragma argsused -int D_Page11(op, code, pc, suffix) -Opcode *op; -int code; -int pc; -char *suffix; -{ - fprintf(fp,"11 "); - code = prog[pc+1]; - return (*optable11[code].display)(&optable11[code], code, pc+1, ""); -} - -#pragma argsused -int D_Immediat(op, code, pc, suffix) -Opcode *op; -int code; -int pc; -char *suffix; -{ - int offset; - - offset = prog[pc+1]; - fprintf(fp,"%0.2X %0.2X %s%s #$%0.2X", - code, offset, suffix, op->name, offset); - return op->bytes; -} - -#pragma argsused -int D_ImmediatL(op, code, pc, suffix) -Opcode *op; -int code; -int pc; -char *suffix; -{ - int offset; - - offset = prog[pc+1] * 256 + prog[pc+2]; - fprintf(fp,"%0.2X %0.2X %0.2X %s%s #$%0.4X", - code, prog[pc+1], prog[pc+2], suffix, op->name, offset); - return op->bytes; -} - -#pragma argsused -int D_Inherent(op, code, pc, suffix) -Opcode *op; -int code; -int pc; -char *suffix; -{ - fprintf(fp,"%0.2X %s%s", code, suffix, op->name); - return op->bytes; -} - -#pragma argsused -int D_OS9(op, code, pc, suffix) -Opcode *op; -int code; -int pc; -char *suffix; -{ - int offset; - - offset = prog[pc+1]; - for(int i =0, j = sizeof(os9sys)/sizeof(struct os9syscall), m = (i+j)/2 ;i<=j; m=(i+j)/2 ) { - if (os9sys[m].code > offset) { - j=m-1; - } else if (os9sys[m].code < offset) { - i=m+1; - } else if (os9sys[m].code == offset) { - fprintf(fp,"%0.2X %0.2X %s%s %s", - code, offset, suffix, op->name, os9sys[m].name); - return op->bytes; - } - } - fprintf(fp,"%0.2X %0.2X %s%s $%0.2X", - code, offset, suffix, op->name, prog[pc+1]); - return op->bytes; -} - -#pragma argsused -char *IndexRegister(postbyte) -int postbyte; -{ - return Indexed_Register[ (postbyte>>5) & 0x03]; -} - -#pragma argsused -int D_Indexed(op, code, pc, suffix) -Opcode *op; -int code; -int pc; -char *suffix; -{ - int postbyte; - char *s; - int extrabytes; - int disp; - int address; - int offset; - - extrabytes = 0; - postbyte = prog[pc+1]; - if ((postbyte & 0x80) == 0x00) { - disp = postbyte & 0x1f; - if ((postbyte & 0x10) == 0x10) { - s = "-"; - disp=0x20-disp; - } - else - s = "+"; - fprintf(fp,"%0.2X %0.2X %s%s %s$%0.2X,%s", - code, postbyte, suffix, op->name, s,disp,IndexRegister(postbyte)); - } else { - switch(postbyte & 0x1f) { - case 0x00 : - fprintf(fp,"%0.2X %0.2X %s%s ,%s+", - code, postbyte, suffix, op->name, IndexRegister(postbyte)); - break; - case 0x01 : - fprintf(fp,"%0.2X %0.2X %s%s ,%s++", - code, postbyte, suffix, op->name, IndexRegister(postbyte)); - break; - case 0x02 : - fprintf(fp,"%0.2X %0.2X %s%s ,-%s", - code, postbyte, suffix, op->name, IndexRegister(postbyte)); - break; - case 0x03 : - fprintf(fp,"%0.2X %0.2X %s%s ,--%s", - code, postbyte, suffix, op->name, IndexRegister(postbyte)); - break; - case 0x04 : - fprintf(fp,"%0.2X %0.2X %s%s ,%s", - code, postbyte, suffix, op->name, IndexRegister(postbyte)); - break; - case 0x05 : - fprintf(fp,"%0.2X %0.2X %s%s B,%s", - code, postbyte, suffix, op->name, IndexRegister(postbyte)); - break; - case 0x06 : - fprintf(fp,"%0.2X %0.2X %s%s A,%s", - code, postbyte, suffix, op->name, IndexRegister(postbyte)); - break; - case 0x07 : - break; - case 0x08 : - offset = prog[pc+2]; - if (offset < 128) - s = "+"; - else { - s = "-"; - offset=0x0100-offset; - } - fprintf(fp,"%0.2X %0.2X %0.2X %s%s %s$%0.2X,%s", - code, postbyte, prog[pc+2], suffix, op->name, s, offset, - IndexRegister(postbyte)); - extrabytes=1; - break; - case 0x09 : - offset = prog[pc+2] * 256 + prog[pc+3]; - if (offset < 32768) - s = "+"; - else { - s = "-"; - offset=0xffff-offset+1; - } - fprintf(fp,"%0.2X %0.2X %0.2X %0.2X %s%s %s$%0.4X,%s", - code, postbyte, prog[pc+2], prog[pc+3], suffix, op->name, s, offset, - IndexRegister(postbyte)); - extrabytes=2; - break; - case 0x0a : - break; - case 0x0b : - fprintf(fp,"%0.2X %0.2X %s%s D,%s", - code, postbyte, suffix, op->name, IndexRegister(postbyte)); - break; - case 0x0c : - offset = (*(char *)(prog+pc+2)+pc+3) & 0xFFFF; - s = "<"; - fprintf(fp,"%0.2X %0.2X %0.2X %s%s %s$%0.2X,PCR", - code, postbyte, prog[pc+2], suffix, op->name, s, offset+adoffset); - extrabytes = 1; - break; - case 0x0d : - offset = prog[pc+2] * 256 + prog[pc+3]; - offset = ((offset>0x7fff? offset-0x10000 : offset )+pc+4) & 0xFFFF; - s = ">"; - fprintf(fp,"%0.2X %0.2X %0.2X %0.2X %s%s %s$%0.4X,PCR", - code, postbyte, prog[pc+2], prog[pc+3], suffix, op->name, s, offset+adoffset); - extrabytes = 2; - break; - case 0x0e : - break; - case 0x0f : - fprintf(fp,"%0.2X %0.2X %s?????", - code, postbyte, suffix); - break; - case 0x10 : - fprintf(fp,"%0.2X %0.2X %s?????", - code, postbyte, suffix); - break; - case 0x11 : - fprintf(fp,"%0.2X %0.2X %s%s [,%s++]", - code, postbyte, suffix, op->name, IndexRegister(postbyte)); - break; - case 0x12 : - fprintf(fp,"%0.2X %0.2X %s?????", - code, postbyte, suffix); - break; - case 0x13 : - fprintf(fp,"%0.2X %0.2X %s%s [,--%s]", - code, postbyte, suffix, op->name, IndexRegister(postbyte)); - break; - case 0x14 : - fprintf(fp,"%0.2X %0.2X %s%s [,%s]", - code, postbyte, suffix, op->name, IndexRegister(postbyte)); - break; - case 0x15 : - fprintf(fp,"%0.2X %0.2X %s%s [B,%s]", - code, postbyte, suffix, op->name, IndexRegister(postbyte)); - break; - case 0x16 : - fprintf(fp,"%0.2X %0.2X %s%s [A,%s]", - code, postbyte, suffix, op->name, IndexRegister(postbyte)); - break; - case 0x17 : - break; - case 0x18 : - offset = prog[pc+2]; - if (offset < 128) - s = "+"; - else { - s = "-"; - offset=0x0100-offset; - } - fprintf(fp,"%0.2X %0.2X %0.2X %s%s [%s$%0.2X,%s]", - code, postbyte, prog[pc+2], suffix, op->name, s, offset, - IndexRegister(postbyte)); - extrabytes = 1; - break; - case 0x19 : - offset = prog[pc+2] * 256 + prog[pc+3]; - if (offset < 32768) - s = "+"; - else { - s = "-"; - offset=0xffff-offset+1; - } - fprintf(fp,"%0.2X %0.2X %0.2X %0.2X %s%s [%s$%0.4X,%s]", - code, postbyte, prog[pc+2], prog[pc+3], suffix, op->name, s, offset, - IndexRegister(postbyte)); - extrabytes = 2; - break; - case 0x1a : - break; - case 0x1b : - fprintf(fp,"%0.2X %0.2X %s%s [D,%s]", - code, postbyte, suffix, op->name, IndexRegister(postbyte)); - break; - case 0x1c : - offset = (*((char*)prog+pc+2)+pc+3) & 0xFFFF; - s = "<"; - fprintf(fp,"%0.2X %0.2X %0.2X %s%s [%s$%0.2X,PCR]", - code, postbyte, prog[pc+2], suffix, op->name, s, offset+adoffset); - extrabytes = 1; - break; - case 0x1d : - offset = prog[pc+2] * 256 + prog[pc+3]; - offset = ((offset>0x7fff?offset-0x8001 : offset )+pc+4) & 0xFFFF; - s = ">"; - fprintf(fp,"%0.2X %0.2X %0.2X %0.2X %s%s [%s$%0.4X,PCR]", - code, postbyte, prog[pc+2], prog[pc+3], suffix, op->name, s, offset+adoffset); - extrabytes = 2; - break; - case 0x1e : - break; - case 0x1f : - address = prog[pc+2] * 256 + prog[pc+3]; - extrabytes = 2; - fprintf(fp,"%0.2X %0.2X %0.2X %0.2X %s%s [$%4X]", - code, postbyte, prog[pc+2], prog[pc+3], suffix, op->name, address); - break; - } - } - return op->bytes + extrabytes; -} - -#pragma argsused -int D_Extended(op, code, pc, suffix) -Opcode *op; -int code; -int pc; -char *suffix; -{ - int offset; - - offset = prog[pc+1] * 256 + prog[pc+2]; - fprintf(fp,"%0.2X %0.2X %0.2X %s%s $%0.4X", - code, prog[pc+1], prog[pc+2], suffix, op->name, offset); - return op->bytes; -} - -#pragma argsused -int D_Relative(op, code, pc, suffix) -Opcode *op; -int code; -int pc; -char *suffix; -{ - int offset; - int disp; - - offset = prog[pc+1]; - if (offset < 127 ) - disp = pc + 2 + offset; - else - disp = pc + 2 - (256 - offset); - fprintf(fp,"%0.2X %0.2X %s%s $%0.4X", - code, offset, suffix, op->name, disp); - return op->bytes; -} - -#pragma argsused -int D_RelativeL(op, code, pc, suffix) -Opcode *op; -int code; -int pc; -char *suffix; -{ - int offset; - int disp; - - offset = prog[pc+1] * 256 + prog[pc+2]; - if (offset < 32767 ) - disp = pc + 3 + offset + adoffset; - else - disp = pc + 3 - (65536 - offset) + adoffset; - fprintf(fp,"%0.2X %0.2X %0.2X %s%s $%0.4X", - code, prog[pc+1], prog[pc+2], suffix, op->name, disp); - return op->bytes; -} - -#pragma argsused -int D_Register0(op, code, pc, suffix) -Opcode *op; -int code; -int pc; -char *suffix; -{ - int postbyte; - - postbyte = prog[pc+1]; - - fprintf(fp,"%0.2X %0.2X %s%s %s,%s", - code, postbyte, suffix, op->name, Inter_Register[postbyte>>4], Inter_Register[postbyte & 0x0F]); - - - return op->bytes; -} - -#pragma argsused -int D_Register1(op, code, pc, suffix) -Opcode *op; -int code; -int pc; -char *suffix; -{ - int postbyte; - int i; - int flag=0; - static char *s_stack[8]={"PC","U","Y","X","DP","B","A","CC"}; - static int bits[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; - - postbyte = prog[pc+1]; - - fprintf(fp,"%0.2X %0.2X %s%s ", - code, postbyte, suffix, op->name); - - for(i=0;i<8;i++) { - if ((postbyte & bits[i]) !=0) { - if (flag !=0) { - fprintf(fp,","); - } else { - flag=1; - } - fprintf(fp,s_stack[i]); - } - } - return op->bytes; -} - -#pragma argsused -int D_Register2(op, code, pc, suffix) -Opcode *op; -int code; -int pc; -char *suffix; -{ - int postbyte; - int i; - int flag=0; - static char *u_stack[8]={"PC","S","Y","X","DP","B","A","CC"}; - static int bits[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; - - postbyte = prog[pc+1]; - fprintf(fp,"%0.2X %0.2X %s%s ", - code, postbyte, suffix, op->name); - - for(i=0;i<8;i++) { - if ((postbyte & bits[i]) !=0) { - if (flag !=0) { - fprintf(fp,","); - } else { - flag=1; - } - fprintf(fp,u_stack[i]); - } - } - return op->bytes; -} - - -void hexadump(b, l, loc, w) -unsigned char *b; -int l; -int loc; -int w; -{ - int i; - int j; - int end; - // char b[4096]; - - // memset(b, '\0', 4096); - // memcpy(b, s, l); - //fprintf(fp,"\n"); - end = ((l%w)>0)?(l/w)+1:(l/w); - for (j=0;j<end;j++) { - fprintf(fp,"%04X: ", loc+j*w+adoffset); - for (i=0;i<w;i++) { - fprintf(fp,"%02X ", b[j*w+i]); - } - fprintf(fp,"|"); - for (i=0;i<w;i++) { - if ((b[j*w+i] >= 0x20) && (b[j*w+i] < 0x7f)) { - fprintf(fp,"%c", b[j*w+i]); - } else { - fprintf(fp,"."); - } - } - fprintf(fp,"|\n"); - } - //fprintf(fp,"\n"); -} - -char *comment(arg) -int arg; -{ - int i; - - for (i=0;i<lastio;i++) { - if (arg == iotable[i]) { - return iocomment[i]; - } - } - return ""; -} - -int disasm(start, end) -int start; -int end; -{ - int pc; - int code; - int currstring; - - currstring = 0; - for (pc=start; pc <= end;) { - code = prog[pc]; - fprintf(fp,"%0.4X: ", pc + adoffset); - if (currstring < laststring) { - if (pc == stringtable[currstring].address) { - hexadump(&prog[pc], stringtable[currstring].length, pc, - stringtable[currstring].width); - pc += stringtable[currstring].length; - currstring++; - continue; - } - } - pc += (*optable[code].display)(&optable[code], code, pc, " "); - fprintf(fp,"\n"); - } - return pc; -} - -#ifndef NO_MAIN - -int main(int argc, char **argv ) -{ - int fd; - int start,end; - int size; - - if ( argc > 2 && *argv[1] == '-') { - if (argv[1][1]=='o') { - adoffset=strtol(argv[2],(char**)0,0); - argc-=2; - argv += 2; - } - } - if ( argc != 4 ) { - fprintf(stderr, "usage: disasm [-o offset] <file> <start> <end>\n"); - fprintf(stderr, " where start and end are in hex.\n"); - exit(1); - } - - sscanf(argv[2],"%x",&start); start -= adoffset; - sscanf(argv[3],"%x",&end); end -= adoffset; - printf("disass %x - %x\n",start,end); - - fp = stdout; - - fd = open(argv[1], O_RDONLY, S_IREAD|S_IWRITE); - size = read(fd, &prog[0x0000], 0xffff); - - if (end > size) end=size; - - disasm(start, end); - close(fd); - return 0; -} - -#endif // NO_MAIN
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/latex2creole.py Mon Jul 23 16:07:12 2018 +0900 @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# coding: utf-8 + +""" + latex2creole + ~~~~~~~~~~~~ + + Hacked script to convert a LaTeX file into creole markup. + + Note: + Some hand-editing is needed. + + :created: 2013 by Jens Diemer - www.jensdiemer.de + :copyleft: 2013 by the DragonPy team, see AUTHORS for more details. + :license: GNU GPL v3 or above, see LICENSE for more details. +""" + +import sys + +sourcefile = r"sbc09/sbc09.tex" +destination = r"sbc09.creole" + + +HEADLINES = ( + r"\title{", + r"\chapter{", + r"\section{", + r"\subsection{", +) +SKIPS = ( + r"\begin", + r"\end", + r"\document", + r"\maketitle", + r"\tableofcontents", + "\\def\\", +) + +in_list = 0 + +def should_skip(line): + for skip in SKIPS: + if line.startswith(skip): + return True + + +with open(sourcefile, "r") as infile: + with open(destination, "w") as outfile: + for line in infile: + # ~ print line + + line = line.strip() + + if line.startswith(r"\begin{itemize}"): + in_list += 1 + continue + if line.startswith(r"\end{itemize}"): + in_list -= 1 + if in_list == 0: + outfile.write("\n") + continue + + if in_list: + if line.startswith(r"\item"): + line = "\n%s%s" % ("*"*in_list, line[5:]) + outfile.write(line) + continue + + if line == r"\begin{verbatim}": + line = "{{{" + elif line == r"\end{verbatim}": + line = "}}}" + + if should_skip(line): + continue + + for no, prefix in enumerate(HEADLINES, 1): + if line.startswith(prefix): + line = line.replace("{\\tt ", "").replace("}", "") + line = line.split("{", 1)[1].replace("{", "").replace("}", "") + line = "\n%(m)s %(l)s %(m)s\n" % { + "m": "="*no, + "l": line + } + break + + if line.startswith(r"\item["): + item, txt = line[6:].split("]") + item = item.strip() + txt = txt.strip() + line = "** %s **\n%s" % (item, txt) + + if "{\\tt" in line: + line = line.replace("{\\tt ", "{{{").replace("}", "}}}") + if "{\\em" in line: + line = line.replace("{\\em ", "{{{").replace("}", "}}}") + + line = line.replace("\\", "") + + print line + line += "\n" + outfile.write(line)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/origin/README Mon Jul 23 16:07:12 2018 +0900 @@ -0,0 +1,13 @@ +This is an unfinished. but working version of the 6809 assewmbler. simulator +and software. It is released under the GPL +It runs under several versions of Unix. Docs are in LaTeX format (sbc09.tex) and +in ASCI (README.doc) + +mon2.asm is an alternative version of the monitor program. + +alt09.rom is a version of the ROM that contains the alternative monitor and +Forth. Forth is transferrred to RAM by a small loader. +To start Forth type G8000. To start it again, type G400. + +Yes, you can run TETRIS from the Forth included with this simulator. +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/origin/basic.txt Mon Jul 23 16:07:12 2018 +0900 @@ -0,0 +1,92 @@ + TINY BASIC SUMMARY + +Editing Standard Basic + +Direct Mode All Verbs Usable + +Statement Types + + PRINT Item List + LET Var = Expr (LET is optional) + IF Expr Relop Expr Statement + INPUT Variable List + GOTO Line Number + GOSUB Line Number + RETURN + POKE POKE(Expr) = Expr + STOP + LIST Line Number, Line Number (Line Numbers are optional) + RUN + NEW + +Functions + + USR Variable = USR(Expr,Expr) + PEEK Variable = PEEK(Expr) + MEM Variable = MEM + +Number Integers to _+32767 or Hex Integers preceded by a $ symbol + +Variable Letters A-Z + +Expression Variables, Numbers, and Functions combined with the following + operators +, -, *, /, (, ). + +Relop Comparison operators =, <, >, <=, >=, <>. + +Line Number Numbers 1 through 9999 + +String "ALPHANUMERICS" + +Item List Expressions and Strings seperated by format control + characters , and ;. + +Control Chars. Control H or "Back Space" deletes last input character. + Control X or "Cancel" deletes entire input line. + Control C Terminates Basic program or List operation and + returns control to command mode. + +Memory Usage Tiny Basic V1.37 + +$0080 - $009F Tiny Basic interpreter scratch area. +$00A0 - $00FD Not used by Tiny Basic interpreter. (usable USR routines) +$**** - $**** Pointer to Interrupt Vector Table. (Identical to LILBUG) +$D800 - $DFFF Input Buffer, Basic Program storage, Stack Space, and + Variables in RAM. +$**** - $**** Optional Power Up Basic Program and/or USR functions in ROM. +$E800 - $EFFF Tiny Basic interpreter ROM. + +$E800 Cold Start Address. +$E803 Warm Start Address. + + Tiny Basic USR Function + +The USR function in Tiny Basic takes 2 arguments and returns a value to a +variable. The form of the USR function is "LET V = USR(Expr,Expr)". +The USR function can be used in any expression in Tiny Basic as an example +"LET V = A * ( B + USR( $EF00, K))". The USR function can also be used with +the PRINT statement. + +The first argument of the USR function is evaluated to determine the address +or the machine language code to be called. The second argument is evaluated +and the value is send to the machine code routine in the D accumulator. The +second argument is optional, if it is present the Carry bit in the condition +code register will be cleared when the machine code routine is called. If the +second argument is not present the Carry Bit will be set when the machine code +is called. The machine code routine may return a result to the BASIC program +in the D accumulator, the value in the D accumulator on return from the machine +code routine will be used by the BASIC program as the value of the function. + +The machine code routine must execute a RTS instruction to return conterol to +the BASIC program. The machine code routine may use all the processor registers +freely and need not save and restore any registers. It is important that the +machine code routine not modify any memory used by the Tiny Basic interpreter. +Consult the memory map provided with your version of Tiny Basic to determine +which memory areas are not used. + +Tiny Basic handles interrupts with the same interrupt vectoring technique used +by LILBUG. Consult the LILBUG manual for details on interrupt vector usage. + + + + JPB 12-APR-82
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/origin/monitor.tex Mon Jul 23 16:07:12 2018 +0900 @@ -0,0 +1,3085 @@ +\documentstyle[a4wide]{report} +\title{A macine language monitor for the 6809 Processor} +\author{L.C. Benschop} +\begin{document} +\maketitle +\tableofcontents +\chapter{Introduction} + +The program {\tt monitor.asm} is a program that is intended to be included +in the ROM of a 6809 based single board computer. The program allows a user +to communicate with the single board computer through a serial port. It +allows a user to enter machine code, examine memory and registers, to set +breakpoints, to trace a program and more. Furthermore, data can be sent to +and be received from the single board computer through the X-MODEM protocol. + +\section{A bit of history.} + +In the seventies you could buy single board microcomputers that had a +hexadecimal keypad and 7-segment displays. These computers typically had +less than 1 kilobyte of RAM and a simple monitor program in ROM. An +interface to a cassette recorder (or paper tape reader/writer) and a +terminal was possible, but not standard. The typical way to program the +machine was entering hexadecimal machine codes on the keypad. Machine code +was the only language in which you could program them, especially if you +only had a hexadecimal keypad and 7-segment led displays. You typically used +these machines to experiment with hardware interfacing, as games and +calculations were a bit limited with only six 7-sengment digits. + +Next came simple home computers, like the TRS80, the Apple ][ and the +Commodore PET. These machines had BASIC in ROM and they used a simple +cassette recorder to store data. These computers had a TV or a low quality +monitor as display and a QWERTY keyboard. These machines could be upgraded +with a floppy disk drive and a printer and then they could be used for +professional work. These machines had 4 to 64 kilobyts of memory. +Apart from assembly language you could use BASIC, Forth +and sometimes Pascal to program these machines. Most useful programs (and +the best games) were programmed in assembly language. Many of these machines +had BASIC in ROM and no machine code monitor. You had to load that +separately. + +Today we have personal computers that run DOS, Windows, Unix or something +else. New computers have 4 to 16 megabytes of RAM and hard disks of more +than 500 Megabytes. Apart from having in the order of 1000 times more +storage, they are also 1000 times faster than the old 8-bit home computers. +Programming? You can use Visual BASIC, C++ and about +every other programming language on the planet. But programs have become +bigger and bigger. Programming is not the same as it was before. + +I guess there is some demand for small 8-bit computer systems that are simple +to build, easy to interface to all kinds of hobby projects, fun to program +and small enough to integrate into a home-built project. +Do we want to use hexadecimal keyboards and 7-segment displays? I guess not +many people want to use them. Do we want to use a cassette recorder for data +storage and a TV as a display? Not me. And if you build your own 8-bit +microprocessor, do you want to waste your time and money on a hexadecimal +keypad or a cassette interface that you do not like to use and that you do +not need anyway? PCs of five years ago are more than adequate to run an +editor, a terminal program and a cross assembler for your favourite 8-bit +processor. If you equip an 8-bit system with some static CMOS RAM, a serial +interface and a monitor in ROM, you can use the keyboard, hard disk and +monitor of your PC for program development and the 8-bit micro can be +disconnected from the PC and do its task, once it is programmed. + +Cross development is nothing special. How do you think the microprocessor in +you microwave was programmed? But it is not practical for a hobbyist to +program an EPROM for each program change. Professional developers of +embedded processors have expensive tools, like ROM emulators, processor +emulators etc. to see what the processor is doing on its way to the next +crash. For a hobbyist it is much more practival to have a slightly more +expensive embedded computer that you can run an interactive debugger on. +And you are not even limited to assembly language. If you have 32k ROM you +can have both the monitor program and a BASIC interpreter and some +aplication code in ROM. Nothing prevents you from having Forth as well. + + +\chapter{Hardware that the program is supposed to run on} + +\chapter{Use of the monitor commands} + +\item{Usage of the memory} + +\chapter{Operating System Facilities} + +\begin{description} +\item[getchar] address \$00. +\item[putchar] address \$03. +\item[getline] address \$06. +\item[putline] address \$09. +\item[putcr] address \$0C. +\item[getpoll] address \$0F. +\item[xopenin] address \$12. +\item[xopenout] address \$15. +\item[xabortin] address \$18. +\item[xclosein] address \$1B. +\item[xcloseout] address \$1E. +\item[delay] address \$21. +\end{description} + + +\end{description} + +\chapter{Extending the built-in Assembler} + +\appendix +\chapter{Assembly listing of monitor program} +{\footnotesize +\begin{verbatim} +0000: ;Buggy machine language monitor and rudimentary O.S. version 1.0 +0000: +0000: * Memory map of SBC +0000: * $0-$40 Zero page variables reserved by monitor and O.S. +0000: * $40-$FF Zero page portion for user programs. +0000: * $100-$17F Xmodem buffer 0, terminal input buffer, +0000: * $180-$1FF Xmodem buffer 1, terminal output buffer. +0000: * $200-$27F Terminal input line. +0000: * $280-$2FF Variables reserved by monitor and O.S. +0000: * $300-$400 System stack. +0000: * $400-$7FFF RAM for user programs and data. +0000: * $8000-$DFFF PROM for user programs. +0000: * $E000-$E1FF I/O addresses. +0000: * $E200-$E3FF Reserved. +0000: * $E400-$FFFF Monitor ROM +0000: +0000: * Reserved Zero page addresses +0000: org $0000 +0000: * First the I/O routine vectors. +0000: getchar rmb 3 ;Jump to getchar routine. +0003: putchar rmb 3 ;Jump to putchar routine. +0006: getline rmb 3 ;Jump to getline routine. +0009: putline rmb 3 ;Jump to putline routine. +000C: putcr rmb 3 ;Jump to putcr routine. +000F: getpoll rmb 3 ;Jump to getpoll routine. +0012: xopenin rmb 3 ;Jump to xopenin routine. +0015: xopenout rmb 3 ;Jump to xopenout routine. +0018: xabortin rmb 3 ;Jump to xabortin routine. +001B: xclosein rmb 3 ;Jump to xclosein routine. +001E: xcloseout rmb 3 ;Jump to xcloseout routine. +0021: delay rmb 3 ;Jump to delay routine. +0024: +0024: *Next the system variables in the zero page. +0024: temp rmb 2 ;hex scanning/disasm +0026: temp2 rmb 2 ;Hex scanning/disasm +0028: temp3 rmb 2 ;Used in Srecords, H command +002A: timer rmb 3 ;3 byte timer, incremented every 20ms +002D: xpacknum rmb 1 ;Packet number for XMODEM block, +002E: xsum rmb 1 ;XMODEM checksum +002F: lastok rmb 1 ;flag to indicate last block was OK +0030: xcount rmb 1 ;Count of characters in buffer. +0031: xmode rmb 1 ;XMODEM mode, 0 none, 1 out, 2 in. +0032: +0032: * I/O buffers. +0032: buflen equ 128 ;Length of input line buffer. +0032: org $100 +0100: buf0 rmb 128 ;Xmodem buffer 0, serial input buffer. +0180: buf1 rmb 128 ;Xmodem buffer 1, serial output buffer. +0200: linebuf rmb buflen ;Input line buffer. +0280: +0280: +0280: * Interrupt vectors (start at $280) +0280: * All interrupts except RESET are vectored through jumps. +0280: * FIRQ is timer interrupt, IRQ is ACIA interrupt. +0280: swi3vec rmb 3 +0283: swi2vec rmb 3 +0286: firqvec rmb 3 +0289: irqvec rmb 3 +028C: swivec rmb 3 +028F: nmivec rmb 3 +0292: xerrvec rmb 3 ;Error handler for XMODEM error. +0295: exprvec rmb 3 ;Expression evaluator in assembler. +0298: asmerrvec rmb 3 ;Error handler for assembler errors. +029B: +029B: * Next the non zero page system variables. +029B: oldpc rmb 2 ;Saved pc value for J command. +029D: addr rmb 2 ;Address parameter. +029F: length rmb 2 ;Length parameter. +02A1: +02A1: brkpoints equ 4 ;Number of settable breakpoints. +02A1: bpaddr rmb brkpoints*3 ;Address and byte for each break point. +02AD: stepbp rmb 3 ;Address of P command break point. +02B0: +02B0: sorg rmb 2 ;Origin address of S record entry. +02B2: soffs rmb 2 ;Offset load adrr-addr in record +02B4: +02B4: oldgetc rmb 2 ;Old getchar address. +02B6: oldputc rmb 2 ;Old putchar address. +02B8: oldputcr rmb 2 ;Old putcr address. +02BA: lastterm rmb 1 ;Last terminating character. +02BB: filler rmb 1 ;Filler at end of XMODEM file. +02BC: xmcr rmb 1 ;end-of-line characters for XMODEM send. +02BD: savesp rmb 2 ;Save sp to restore it on error. +02BF: +02BF: * Following variables are used by assembler/disassembler. +02BF: prebyte rmb 1 +02C0: opc1 rmb 1 +02C1: opcode rmb 1 +02C2: postbyte rmb 1 +02C3: amode rmb 1 +02C4: operand rmb 2 +02C6: mnembuf rmb 5 ;Buffer to store capitalized mnemonic. +02CB: opsize rmb 1 ;SIze (in bytes) of extra oeprand (0--2) +02CC: uncert rmb 1 ;Flag to indicate that op is unknown. +02CD: dpsetting rmb 2 +02CF: +02CF: endvars equ * +02CF: +02CF: ramstart equ $400 ;first free RAM address. +02CF: +02CF: ramtop equ $8000 ;top of RAM. +02CF: +02CF: * I/O port addresses +02CF: aciactl equ $e000 ;Control port of ACIA +02CF: aciasta equ $e000 ;Status port of ACIA +02CF: aciadat equ $e001 ;Data port of ACIA +02CF: +02CF: * ASCII control characters. +02CF: SOH equ 1 +02CF: EOT equ 4 +02CF: ACK equ 6 +02CF: BS equ 8 +02CF: LF equ 10 +02CF: CR equ 13 +02CF: NAK equ 21 +02CF: CAN equ 24 +02CF: DEL equ 127 +02CF: +02CF: CASEMASK equ $DF ;Mask to make lowercase into uppercase. +02CF: +02CF: * Monitor ROM starts here. +02CF: org $E400 +E400: +E400: 1AFF reset orcc #$FF ;Disable interrupts. +E402: 4F clra +E403: 1F8B tfr a,dp ;Set direct page register to 0. +E405: 10CE0400 lds #ramstart +E409: 8EE4FF ldx #intvectbl +E40C: CE0280 ldu #swi3vec +E40F: C61B ldb #osvectbl-intvectbl +E411: 8D37 bsr blockmove ;Initialize interrupt vectors from ROM. +E413: 8EE51A ldx #osvectbl +E416: CE0000 ldu #0 +E419: C624 ldb #endvecs-osvectbl +E41B: 8D2D bsr blockmove ;Initialize I/O vectors from ROM. +E41D: 8D33 bsr initacia ;Initialize serial port. +E41F: 1C00 andcc #$0 ;Enable interrupts +E421: * Put the 'saved' registers of the program being monitored on top of the +E421: * stack. There are 12 bytes on the stack for cc,b,a,dp,x,y,u and pc +E421: * pc is initialized to $400, the rest to zero. +E421: 8E0000 ldx #0 +E424: 1F12 tfr x,y +E426: CE0400 ldu #ramstart +E429: 3450 pshs x,u +E42B: 3430 pshs x,y +E42D: 3430 pshs x,y +E42F: 8E029B ldx #oldpc +E432: C634 ldb #endvars-oldpc +E434: 6F80 clvar clr ,x+ +E436: 5A decb +E437: 26FB bne clvar ;Clear the variable area. +E439: CC1A03 ldd #$1A03 +E43C: FD02BB std filler ;Set XMODEM filler and end-of-line. +E43F: 8EE5C1 ldx #welcome +E442: BDE4E1 jsr outcount +E445: 9D0C jsr putcr ;Print a welcome message. +E447: 7EE558 jmp cmdline +E44A: * Block move routine, from X to U length B. Modifies them all and A. +E44A: A680 blockmove lda ,x+ +E44C: A7C0 sta ,u+ +E44E: 5A decb +E44F: 26F9 bne blockmove +E451: 39 rts +E452: +E452: * Initialize serial communications port, buffers, interrupts. +E452: C603 initacia ldb #$03 +E454: F7E000 stb aciactl +E457: C635 ldb #%00110101 +E459: 39 rts +E45A: +E45A: * O.S. routine to read a character into B register. +E45A: F6E000 osgetc ldb aciasta +E45D: C501 bitb #$01 +E45F: 27F9 beq osgetc +E461: F6E001 ldb aciadat +E464: 39 rts +E465: +E465: ;O.S. rotuine to check if there is a character ready to be read. +E465: F6E000 osgetpoll ldb aciasta +E468: C501 bitb #$01 +E46A: 2602 bne poltrue +E46C: 5F clrb +E46D: 39 rts +E46E: C6FF poltrue ldb #$ff +E470: 39 rts +E471: +E471: * O.S. routine to write the character in the B register. +E471: 3402 osputc pshs a +E473: B6E000 putcloop lda aciasta +E476: 8502 bita #$02 +E478: 27F9 beq putcloop +E47A: F7E001 stb aciadat +E47D: 3502 puls a +E47F: 39 rts +E480: +E480: * O.S. routine to read a line into memory at address X, at most B chars +E480: * long, return actual length in B. Permit backspace editing. +E480: 3412 osgetl pshs a,x +E482: D724 stb temp +E484: 4F clra +E485: 9D00 osgetl1 jsr getchar +E487: C47F andb #$7F +E489: C108 cmpb #BS +E48B: 2704 beq backsp +E48D: C17F cmpb #DEL +E48F: 2614 bne osgetl2 +E491: 4D backsp tsta ;Recognize BS and DEL as backspace key. +E492: 27F1 beq osgetl1 ;ignore if line already zero length. +E494: C608 ldb #BS +E496: 9D03 jsr putchar +E498: C620 ldb #' ' +E49A: 9D03 jsr putchar +E49C: C608 ldb #BS ;Send BS,space,BS. This erases last +E49E: 9D03 jsr putchar ;character on most terminals. +E4A0: 301F leax -1,x ;Decrement address. +E4A2: 4A deca +E4A3: 20E0 bra osgetl1 +E4A5: C10D osgetl2 cmpb #CR +E4A7: 2704 beq newline +E4A9: C10A cmpb #LF +E4AB: 2607 bne osgetl3 ;CR or LF character ends line. +E4AD: 9D0C newline jsr putcr +E4AF: 1F89 tfr a,b ;Move length to B +E4B1: 3512 puls a,x ;restore registers. +E4B3: 39 rts ;<--- Here is the exit point. +E4B4: C120 osgetl3 cmpb #' ' +E4B6: 25CD blo osgetl1 ;Ignore control characters. +E4B8: 9124 cmpa temp +E4BA: 27C9 beq osgetl1 ;Ignore char if line full. +E4BC: 9D03 jsr putchar ;Echo the character. +E4BE: E780 stb ,x+ ;Store it in memory. +E4C0: 4C inca +E4C1: 20C2 bra osgetl1 +E4C3: +E4C3: * O.S. routine to write a line starting at address X, B chars long. +E4C3: 3416 osputl pshs a,b,x +E4C5: 1F98 tfr b,a +E4C7: 4D tsta +E4C8: 2707 beq osputl1 +E4CA: E680 osputl2 ldb ,x+ +E4CC: 9D03 jsr putchar +E4CE: 4A deca +E4CF: 26F9 bne osputl2 +E4D1: 3516 osputl1 puls a,b,x +E4D3: 39 rts +E4D4: +E4D4: * O.S. routine to terminate a line. +E4D4: 3404 oscr pshs b +E4D6: C60D ldb #CR +E4D8: 9D03 jsr putchar +E4DA: C60A ldb #LF +E4DC: 9D03 jsr putchar ;Send the CR and LF characters. +E4DE: 3504 puls b +E4E0: 39 rts +E4E1: +E4E1: * Output a counted string at addr X +E4E1: 3414 outcount pshs x,b +E4E3: E680 ldb ,x+ +E4E5: 9D09 jsr putline +E4E7: 3514 puls x,b +E4E9: 39 rts +E4EA: +E4EA: 0C2C timerirq inc timer+2 +E4EC: 2608 bne endirq +E4EE: 0C2B inc timer+1 +E4F0: 2604 bne endirq +E4F2: 0C2A inc timer +E4F4: 3B rti +E4F5: 12 aciairq nop +E4F6: 3B endirq rti +E4F7: +E4F7: * Wait D times 20ms. +E4F7: D32B osdly addd timer+1 +E4F9: 10932B dlyloop cmpd timer+1 +E4FC: 26FB bne dlyloop +E4FE: 39 rts +E4FF: +E4FF: * This table will be copied to the interrupt vector area in RAM. +E4FF: 7EE4F6 intvectbl jmp endirq +E502: 7EE4F6 jmp endirq +E505: 7EE4EA jmp timerirq +E508: 7EE4F5 jmp aciairq +E50B: 7EE549 jmp unlaunch +E50E: 7EE4F6 jmp endirq +E511: 7EEDED jmp xerrhand +E514: 7EF69B jmp expr +E517: 7E0298 jmp asmerrvec +E51A: * And this one to the I/O vector table. +E51A: 7EE45A osvectbl jmp osgetc +E51D: 7EE471 jmp osputc +E520: 7EE480 jmp osgetl +E523: 7EE4C3 jmp osputl +E526: 7EE4D4 jmp oscr +E529: 7EE465 jmp osgetpoll +E52C: 7EECE6 jmp xopin +E52F: 7EED09 jmp xopout +E532: 7EED2E jmp xabtin +E535: 7EED71 jmp xclsin +E538: 7EED4E jmp xclsout +E53B: 7EE4F7 jmp osdly +E53E: endvecs equ * +E53E: +E53E: * The J command returns here. +E53E: 3410 stakregs pshs x ;Stack something where the pc comes +E540: 347F pshs ccr,b,a,dp,x,y,u ;Stack the normal registers. +E542: BE029B ldx oldpc +E545: AF6A stx 10,s ;Stack the old pc value. +E547: 2007 bra unlaunch1 +E549: * The G and P commands return here through a breakpoint. +E549: * Registers are already stacked. +E549: EC6A unlaunch ldd 10,s +E54B: 830001 subd #1 +E54E: ED6A std 10,s ;Decrement pc before breakpoint +E550: 1C00 unlaunch1 andcc #$0 ;reenable the interrupts. +E552: BDE970 jsr disarm ;Disarm the breakpoints. +E555: BDE8C5 jsr dispregs +E558: 9D1E cmdline jsr xcloseout +E55A: 10FF02BD sts savesp +E55E: 8E0200 ldx #linebuf +E561: C680 ldb #buflen +E563: 9D06 jsr getline +E565: 5D tstb +E566: 27F0 beq cmdline ;Ignore line if it is empty +E568: 3A abx +E569: 6F84 clr ,x ;Make location after line zero. +E56B: 8E0200 ldx #linebuf +E56E: E680 ldb ,x+ +E570: C4DF andb #CASEMASK ;Make 1st char uppercase. +E572: C041 subb #'A' +E574: 253E bcs unk +E576: C11A cmpb #26 +E578: 243A bcc unk ;Unknown cmd if it is not a letter. +E57A: 8EE580 ldx #cmdtab +E57D: 58 aslb ;Index into command table. +E57E: 6E95 jmp [b,x] +E580: +E580: FBA4E9A6E5B4E7 cmdtab fdb asm,break,unk,dump +E588: E7BDEB56E86AE8 fdb enter,find,go,hex +E590: E824E879E5B4E5 fdb inp,jump,unk,unk +E598: EB19E5B4E5B4E8 fdb move,unk,unk,prog +E5A0: E5B4E90CEA14E8 fdb unk,regs,srec,trace +E5A8: F644E5B4E5B4ED fdb unasm,unk,unk,xmodem +E5B0: E5B4E5B4 fdb unk,unk +E5B4: +E5B4: * Unknown command handling routine. +E5B4: 9D18 unk jsr xabortin +E5B6: 8EE5DE ldx #unknown +E5B9: BDE4E1 jsr outcount +E5BC: 9D0C jsr putcr +E5BE: 7EE558 jmp cmdline +E5C1: +E5C1: +E5C1: +E5C1: * Here are some useful messages. +E5C1: 1C welcome fcb unknown-welcome-1 +E5C2: 57656C636F6D65 fcc "Welcome to BUGGY version 1.0" +E5DE: 0F unknown fcb brkmsg-unknown-1 +E5DF: 556E6B6E6F776E fcc "Unknown command" +E5EE: 0E brkmsg fcb clrmsg-brkmsg-1 +E5EF: 427265616B706F fcc "Breakpoint set" +E5FD: 12 clrmsg fcb fullmsg-clrmsg-1 +E5FE: 427265616B706F fcc "Breakpoint cleared" +E610: 10 fullmsg fcb smsg-fullmsg-1 +E611: 427265616B706F fcc "Breakpoints full" +E621: 11 smsg fcb lastrec-smsg-1 +E622: 4572726F722069 fcc "Error in S record" +E633: 0A lastrec fcb xsmsg-lastrec-1 +E634: 53393033303030 fcc "S9030000FC" +E63E: 11 xsmsg fcb xrmsg-xsmsg-1 +E63F: 53746172742058 fcc "Start XMODEM Send" +E650: 14 xrmsg fcb xamsg-xrmsg-1 +E651: 53746172742058 fcc "Start XMODEM Receive" +E665: 17 xamsg fcb invmmsg-xamsg-1 +E666: 584D4F44454D20 fcc "XMODEM transfer aborted" +E67D: 10 invmmsg fcb exprmsg-invmmsg-1 +E67E: 496E76616C6964 fcc "Invalid mnemonic" +E68E: 10 exprmsg fcb modemsg-exprmsg-1 +E68F: 45787072657373 fcc "Expression error" +E69F: 15 modemsg fcb brmsg-modemsg-1 +E6A0: 41646472657373 fcc "Addressing mode error" +E6B5: 0F brmsg fcb endmsg-brmsg-1 +E6B6: 4272616E636820 fcc "Branch too long" +E6C5: endmsg equ * +E6C5: +E6C5: * Output hex digit contained in A +E6C5: 8B90 hexdigit adda #$90 +E6C7: 19 daa +E6C8: 8940 adca #$40 +E6CA: 19 daa ;It's the standard conversion trick ascii +E6CB: 1F89 tfr a,b ;to hex without branching. +E6CD: 9D03 jsr putchar +E6CF: 39 rts +E6D0: +E6D0: * Output contents of A as two hex digits +E6D0: 3402 outbyte pshs a +E6D2: 44 lsra +E6D3: 44 lsra +E6D4: 44 lsra +E6D5: 44 lsra +E6D6: 8DED bsr hexdigit +E6D8: 3502 puls a +E6DA: 840F anda #$0f +E6DC: 20E7 bra hexdigit +E6DE: +E6DE: * Output contents of d as four hex digits +E6DE: 3404 outd pshs b +E6E0: 8DEE bsr outbyte +E6E2: 3502 puls a +E6E4: 8DEA bsr outbyte +E6E6: 39 rts +E6E7: +E6E7: * Skip X past spaces, B is first non-space character. +E6E7: E680 skipspace ldb ,x+ +E6E9: C120 cmpb #' ' +E6EB: 27FA beq skipspace +E6ED: 39 rts +E6EE: +E6EE: * Convert ascii hex digit in B register to binary Z flag set if no hex digit. +E6EE: C030 convb subb #'0' +E6F0: 2513 blo convexit +E6F2: C109 cmpb #9 +E6F4: 230C bls cb2 +E6F6: C4DF andb #CASEMASK ;Make uppercase. +E6F8: C007 subb #7 ;If higher than digit 9 it must be a letter. +E6FA: C109 cmpb #9 +E6FC: 2307 bls convexit +E6FE: C10F cmpb #15 +E700: 2203 bhi convexit +E702: 1CFB cb2 andcc #$FB ;clear zero +E704: 39 rts +E705: 1A04 convexit orcc #$04 +E707: 39 rts +E708: +E708: DC24 scanexit ldd temp +E70A: 301F leax -1,x +E70C: 0D26 tst temp2 +E70E: 39 rts <-- exit point of scanhex +E70F: +E70F: * Scan for hexadecimal number at address X return in D, Z flag is set it no +E70F: * number found. +E70F: 0F24 scanhex clr temp +E711: 0F25 clr temp+1 +E713: 0F26 clr temp2 +E715: 8DD0 bsr skipspace +E717: BDE6EE scloop jsr convb +E71A: 27EC beq scanexit +E71C: 3404 pshs b +E71E: DC24 ldd temp +E720: 58 aslb +E721: 49 rola +E722: 58 aslb +E723: 49 rola +E724: 58 aslb +E725: 49 rola +E726: 58 aslb +E727: 49 rola +E728: EBE0 addb ,s+ +E72A: DD24 std temp +E72C: 0C26 inc temp2 +E72E: E680 ldb ,x+ +E730: 20E5 bra scloop +E732: +E732: FD029F scan2parms std length +E735: 8DD8 bsr scanhex +E737: 2710 beq sp2 +E739: FD029D std addr +E73C: 8DA9 bsr skipspace +E73E: C12C cmpb #',' +E740: 2607 bne sp2 +E742: 8DCB bsr scanhex +E744: 2703 beq sp2 +E746: FD029F std length +E749: 39 sp2 rts +E74A: +E74A: * Scan two hexdigits at in and convert to byte into A, Z flag if error. +E74A: 8D9B scanbyte bsr skipspace +E74C: 8DA0 bsr convb +E74E: 2712 beq sb1 +E750: 1F98 tfr b,a +E752: E680 ldb ,x+ +E754: 8D98 bsr convb +E756: 270A beq sb1 +E758: 48 asla +E759: 48 asla +E75A: 48 asla +E75B: 48 asla +E75C: D724 stb temp +E75E: 9B24 adda temp +E760: 1CFB andcc #$fb ;Clear zero flag +E762: 39 sb1 rts +E763: +E763: +E763: * This is the code for the D command, hex/ascii dump of memory +E763: * Syntax: D or D<addr> or D<addr>,<length> +E763: 8E0201 dump ldx #linebuf+1 +E766: CC0040 ldd #$40 +E769: BDE732 jsr scan2parms ;Scan address and length, default length=64 +E76C: 10BE029D ldy addr +E770: 8610 dh1 lda #16 +E772: 9725 sta temp+1 +E774: 1F20 tfr y,d +E776: BDE6DE jsr outd +E779: C620 ldb #' ' +E77B: 9D03 jsr putchar +E77D: A6A0 dh2 lda ,y+ ;display row of 16 mem locations as hex +E77F: BDE6D0 jsr outbyte +E782: C620 ldb #' ' +E784: 9625 lda temp+1 +E786: 8109 cmpa #9 +E788: 2602 bne dh6 +E78A: C62D ldb #'-' ;Do a - after the eighth byte. +E78C: 9D03 dh6 jsr putchar +E78E: 0A25 dec temp+1 +E790: 26EB bne dh2 +E792: 3130 leay -16,y ;And now for the ascii dump. +E794: 8610 lda #16 +E796: E6A0 dh3 ldb ,y+ +E798: C120 cmpb #' ' +E79A: 2402 bhs dh4 +E79C: C62E ldb #'.' +E79E: C17F dh4 cmpb #DEL +E7A0: 2502 blo dh5 +E7A2: C62E ldb #'.' ;Convert all nonprintables to . +E7A4: 9D03 dh5 jsr putchar +E7A6: 4A deca +E7A7: 26ED bne dh3 +E7A9: 9D0C jsr putcr +E7AB: FC029F ldd length +E7AE: 830010 subd #16 +E7B1: FD029F std length +E7B4: 22BA bhi dh1 +E7B6: 10BF029D sty addr +E7BA: 7EE558 jmp cmdline +E7BD: +E7BD: * This is the code for the E command, enter hex bytes or ascii string. +E7BD: * Syntax E or E<addr> or E<addr> <bytes> or E<addr>"string" +E7BD: 8E0201 enter ldx #linebuf+1 +E7C0: BDE70F jsr scanhex +E7C3: 2703 beq ent1 +E7C5: FD029D std addr +E7C8: 8D26 ent1 bsr entline +E7CA: 1026FD8A lbne cmdline ;No bytes, then enter interactively. +E7CE: C645 ent2 ldb #'E' +E7D0: 9D03 jsr putchar +E7D2: FC029D ldd addr +E7D5: BDE6DE jsr outd +E7D8: C620 ldb #' ' +E7DA: 9D03 jsr putchar ;Display Eaddr + space +E7DC: 8E0200 ldx #linebuf +E7DF: C680 ldb #buflen +E7E1: 9D06 jsr getline ;Get the line. +E7E3: 3A abx +E7E4: 6F84 clr ,x +E7E6: 8E0200 ldx #linebuf +E7E9: 8D05 bsr entline +E7EB: 26E1 bne ent2 +E7ED: 7EE558 jmp cmdline +E7F0: +E7F0: * Enter a line of hex bytes or ascci string at address X, Z if empty. +E7F0: BDE6E7 entline jsr skipspace +E7F3: 5D tstb +E7F4: 272B beq entexit +E7F6: C122 cmpb #'"' +E7F8: 270F beq entasc +E7FA: 301F leax -1,x +E7FC: 10BE029D ldy addr +E800: BDE74A entl2 jsr scanbyte ;Enter hex digits. +E803: 2715 beq entdone +E805: A7A0 sta ,y+ +E807: 20F7 bra entl2 +E809: 10BE029D entasc ldy addr +E80D: A680 entl3 lda ,x+ +E80F: 4D tsta +E810: 2708 beq entdone +E812: 8122 cmpa #'"' +E814: 2704 beq entdone +E816: A7A0 sta ,y+ +E818: 20F3 bra entl3 +E81A: 10BF029D entdone sty addr +E81E: 1CFB andcc #$fb +E820: 39 rts +E821: 1A04 entexit orcc #$04 +E823: 39 rts +E824: +E824: *This is the code for the I command, display the contents of an address +E824: * Syntax: Iaddr +E824: 8E0201 inp ldx #linebuf+1 +E827: BDE70F jsr scanhex +E82A: 1F01 tfr d,x +E82C: A684 lda ,x ;Read the byte from memory. +E82E: BDE6D0 jsr outbyte ;Display itin hex. +E831: 9D0C jsr putcr +E833: 7EE558 jmp cmdline +E836: +E836: *This is the code for the H command, display result of simple hex expression +E836: *Syntax Hhexnum{+|-hexnum} +E836: 8E0201 hex ldx #linebuf+1 +E839: BDE70F jsr scanhex +E83C: DD28 std temp3 +E83E: BDE6E7 hexloop jsr skipspace +E841: C12B cmpb #'+' +E843: 2609 bne hex1 +E845: BDE70F jsr scanhex +E848: D328 addd temp3 +E84A: DD28 std temp3 +E84C: 20F0 bra hexloop +E84E: C12D hex1 cmpb #'-' +E850: 260E bne hexend +E852: BDE70F jsr scanhex +E855: 53 comb +E856: 43 coma +E857: C30001 addd #1 +E85A: D328 addd temp3 +E85C: DD28 std temp3 +E85E: 20DE bra hexloop +E860: DC28 hexend ldd temp3 +E862: BDE6DE jsr outd +E865: 9D0C jsr putcr +E867: 7EE558 jmp cmdline +E86A: +E86A: * This is the code for the G command, jump to the program +E86A: * Syntax G or G<addr> +E86A: 8E0201 go ldx #linebuf+1 +E86D: BDE70F jsr scanhex +E870: 2702 beq launch +E872: ED6A std 10,s ;Store parameter in pc location. +E874: BDE98A launch jsr arm ;Arm the breakpoints. +E877: 35FF puls ccr,b,a,dp,x,y,u,pc +E879: +E879: * This is the code for the J command, run a subroutine. +E879: * Syntax J<addr> +E879: 8E0201 jump ldx #linebuf+1 +E87C: EC6A ldd 10,s +E87E: FD029B std oldpc ;Save old pc +E881: BDE70F jsr scanhex +E884: ED6A std 10,s ;Store parameter in PC location +E886: 1F41 tfr s,x +E888: 327E leas -2,s +E88A: 1F43 tfr s,u +E88C: C60C ldb #12 ;Move the saved register set 2 addresses +E88E: BDE44A jsr blockmove ;down on the stack. +E891: CCE53E ldd #stakregs +E894: ED6C std 12,s ;Prepare subroutine return address. +E896: 20DC bra launch ;Jump to the routine. +E898: +E898: +E898: * This is the code for the P command, run instruction followed by breakpoint +E898: * Syntax P +E898: 10AE6A prog ldy 10,s ;Get program counter value. +E89B: BDF36B jsr disdecode ;Find out location past current insn. +E89E: 10BF02AD sty stepbp +E8A2: 20D0 bra launch +E8A4: +E8A4: * This is the code for the T command, single step trace an instruction. +E8A4: * Syntax T +E8A4: 7EE558 trace jmp cmdline +E8A7: +E8A7: * Display the contents of 8 bit register, name in B, contents in A +E8A7: 9D03 disp8 jsr putchar +E8A9: C63D ldb #'=' +E8AB: 9D03 jsr putchar +E8AD: BDE6D0 jsr outbyte +E8B0: C620 ldb #' ' +E8B2: 9D03 jsr putchar +E8B4: 39 rts +E8B5: +E8B5: * Display the contents of 16 bit register, name in B, contents in Y +E8B5: 9D03 disp16 jsr putchar +E8B7: C63D ldb #'=' +E8B9: 9D03 jsr putchar +E8BB: 1F20 tfr y,d +E8BD: BDE6DE jsr outd +E8C0: C620 ldb #' ' +E8C2: 9D03 jsr putchar +E8C4: 39 rts +E8C5: +E8C5: * Display the contents of the registers and disassemble instruction at +E8C5: * PC location. +E8C5: C658 dispregs ldb #'X' +E8C7: 10AE66 ldy 6,s ;Note that there's one return address on +E8CA: 8DE9 bsr disp16 ;stack so saved register offsets are +E8CC: C659 ldb #'Y' ;inremented by 2. +E8CE: 10AE68 ldy 8,s +E8D1: 8DE2 bsr disp16 +E8D3: C655 ldb #'U' +E8D5: 10AE6A ldy 10,s +E8D8: 8DDB bsr disp16 +E8DA: C653 ldb #'S' +E8DC: 1F42 tfr s,y +E8DE: 312E leay 14,y ;S of the running program is 12 higher, +E8E0: ;because regs are not stacked when running. +E8E0: 8DD3 bsr disp16 +E8E2: C641 ldb #'A' +E8E4: A663 lda 3,s +E8E6: 8DBF bsr disp8 +E8E8: C642 ldb #'B' +E8EA: A664 lda 4,s +E8EC: 8DB9 bsr disp8 +E8EE: C644 ldb #'D' +E8F0: A665 lda 5,s +E8F2: 8DB3 bsr disp8 +E8F4: C643 ldb #'C' +E8F6: A662 lda 2,s +E8F8: 8DAD bsr disp8 +E8FA: 9D0C jsr putcr +E8FC: C650 ldb #'P' +E8FE: 10AE6C ldy 12,s +E901: 8DB2 bsr disp16 +E903: BDF36B jsr disdecode +E906: BDF44E jsr disdisp ;Disassemble instruction at PC +E909: 9D0C jsr putcr +E90B: 39 rts +E90C: +E90C: +E90C: * This is the code for the R command, display or alter the registers. +E90C: * Syntax R or R<letter><hex> +E90C: 8E0201 regs ldx #linebuf+1 +E90F: BDE6E7 jsr skipspace +E912: 5D tstb +E913: 2605 bne setreg +E915: 8DAE bsr dispregs ;Display regs ifnothing follows. +E917: 7EE558 jmp cmdline +E91A: 108EE966 setreg ldy #regtab +E91E: 4F clra +E91F: C4DF andb #CASEMASK ;Make letter uppercase. +E921: 6DA4 sr1 tst ,y +E923: 1027FC8D lbeq unk ;At end of register tab, unknown reg +E927: E1A0 cmpb ,y+ +E929: 2703 beq sr2 ;Found the register? +E92B: 4C inca +E92C: 20F3 bra sr1 +E92E: 3402 sr2 pshs a +E930: BDE70F jsr scanhex ;Convert the hex argument. +E933: 3406 pshs d +E935: A662 lda 2,s ;Get register number. +E937: 8104 cmpa #4 +E939: 2409 bcc sr3 +E93B: E661 ldb 1,s ;It's 8 bit. +E93D: 3263 leas 3,s ;Remove temp stuff from stack. +E93F: E7E6 stb a,s ;Store it in the reg on stack. +E941: 7EE558 jmp cmdline +E944: 8108 sr3 cmpa #8 +E946: 240C bcc sr4 +E948: 3510 puls x ;It's 16 bit. +E94A: 3261 leas 1,s +E94C: 48 lsla +E94D: 8004 suba #4 ;Convert reg no to stack offset. +E94F: AFE6 stx a,s +E951: 7EE558 jmp cmdline +E954: 3540 sr4 puls u ;It's the stack pointer. +E956: 3261 leas 1,s +E958: 3354 leau -12,u +E95A: 1F41 tfr s,x +E95C: 1F34 tfr u,s ;Set new stack pointer. +E95E: C60C ldb #12 +E960: BDE44A jsr blockmove ;Move register set to new stack location. +E963: 7EE558 jmp cmdline +E966: +E966: 43414244585955 regtab FCC "CABDXYUPS " +E970: +E970: * Disarm the breakpoints, this is replace the SWI instructions with the +E970: * original byte. +E970: 8E02A1 disarm ldx #bpaddr +E973: 8605 lda #brkpoints+1 +E975: EE81 disarm1 ldu ,x++ +E977: E680 ldb ,x+ ;Get address in u, byte in b +E979: 11830000 cmpu #0 +E97D: 2702 beq disarm2 +E97F: E7C4 stb ,u +E981: 4A disarm2 deca +E982: 26F1 bne disarm1 +E984: CE0000 ldu #0 +E987: EF1D stu -3,x ;Clear the step breakpoint. +E989: 39 rts +E98A: +E98A: * Arm the breakponts, this is replace the byte at the breakpoint address +E98A: * with an SWI instruction. +E98A: 8E02AD arm ldx #bpaddr+brkpoints*3 +E98D: 8605 lda #brkpoints+1 ;Arm them in reverse order of disarming. +E98F: EE84 arm1 ldu ,x ;Get address in u. +E991: 270D beq arm2 +E993: E6C4 ldb ,u +E995: E702 stb 2,x +E997: 11A36C cmpu 12,s ;Compare to program counter location +E99A: 2704 beq arm2 +E99C: C63F ldb #$3F +E99E: E7C4 stb ,u ;Store SWI instruction if not equal. +E9A0: 301D arm2 leax -3,x +E9A2: 4A deca +E9A3: 26EA bne arm1 +E9A5: 39 rts +E9A6: +E9A6: * This is the code for the break command, set, clear display breakpoints. +E9A6: * Syntax B or B<addr>. B displays, B<addr> sets or clears breakpoint. +E9A6: 8604 break lda #brkpoints +E9A8: 9727 sta temp2+1 ;Store number of breakpoints to visit. +E9AA: 8E0201 ldx #linebuf+1 +E9AD: BDE70F jsr scanhex +E9B0: 273B beq dispbp ;No number then display breakpoints +E9B2: 8E02A1 ldx #bpaddr +E9B5: CE0000 ldu #0 +E9B8: 1F32 tfr u,y +E9BA: 10A384 bp1 cmpd ,x +E9BD: 2720 beq clearit ;Found the breakpoint, so clear it, +E9BF: 11A384 cmpu ,x ;Is location zero +E9C2: 2602 bne bp2 +E9C4: 1F12 tfr x,y ;Set free address to y +E9C6: 3003 bp2 leax 3,x +E9C8: 0A27 dec temp2+1 +E9CA: 26EE bne bp1 +E9CC: 108C0000 cmpy #0 ;Address not found in list of breakpoints +E9D0: 2716 beq bpfull ;Was free address found. +E9D2: EDA4 std ,y ;If so, store breakpoint there. +E9D4: 8EE5EE ldx #brkmsg +E9D7: BDE4E1 bpexit jsr outcount +E9DA: 9D0C jsr putcr +E9DC: 7EE558 jmp cmdline +E9DF: 4F clearit clra +E9E0: 5F clrb +E9E1: ED84 std ,x +E9E3: 8EE5FD ldx #clrmsg +E9E6: 20EF bra bpexit +E9E8: 8EE610 bpfull ldx #fullmsg +E9EB: 20EA bra bpexit +E9ED: +E9ED: 8E02A1 dispbp ldx #bpaddr +E9F0: EC84 dbp1 ldd ,x +E9F2: 2707 beq dbp2 +E9F4: BDE6DE jsr outd +E9F7: C620 ldb #' ' +E9F9: 9D03 jsr putchar +E9FB: 3003 dbp2 leax 3,x +E9FD: 0A27 dec temp2+1 +E9FF: 26EF bne dbp1 +EA01: 9D0C jsr putcr +EA03: 7EE558 jmp cmdline +EA06: +EA06: * Scan hex byte into a and add it to check sum in temp2+1 +EA06: BDE74A addchk jsr scanbyte +EA09: 10270077 lbeq srecerr +EA0D: 1F89 tfr a,b +EA0F: DB27 addb temp2+1 +EA11: D727 stb temp2+1 +EA13: 39 rts +EA14: +EA14: * This tis the code for the S command, the Motorola S records entry. +EA14: * Syntax SO<addr> or SS<addr>,<len> or S1<bytes> or S9<bytes> +EA14: 8E0201 srec ldx #linebuf+1 +EA17: E680 ldb ,x+ +EA19: C4DF andb #CASEMASK +EA1B: C14F cmpb #'O' +EA1D: 2772 beq setsorg +EA1F: C153 cmpb #'S' +EA21: 277C beq sendrec +EA23: E61F ldb -1,x +EA25: 0F28 clr temp3 +EA27: C131 cmpb #'1' +EA29: 2706 beq readrec +EA2B: C139 cmpb #'9' +EA2D: 2655 bne srecerr +EA2F: 0C28 inc temp3 +EA31: 0F27 readrec clr temp2+1 ;clear checksum. +EA33: 8DD1 bsr addchk +EA35: 8002 suba #2 ;discount the address bytes from the count. +EA37: 9729 sta temp3+1 ;Read length byte. +EA39: 8DCB bsr addchk +EA3B: 3402 pshs a +EA3D: 8DC7 bsr addchk +EA3F: 3504 puls b +EA41: 1E89 exg a,b ;Read address into d. +EA43: FE02B0 ldu sorg +EA46: 270F beq rr1 +EA48: FE02B2 ldu soffs +EA4B: 260A bne rr1 +EA4D: 3406 pshs d ;Sorg is nonzero and soffs is zero, now +EA4F: B302B0 subd sorg ;set soffs +EA52: FD02B2 std soffs +EA55: 3506 puls d +EA57: B302B2 rr1 subd soffs ;Subtract the address offset. +EA5A: 1F02 tfr d,y +EA5C: 8DA8 rr2 bsr addchk +EA5E: 0A29 dec temp3+1 +EA60: 2704 beq endrec +EA62: A7A0 sta ,y+ +EA64: 20F6 bra rr2 +EA66: 0C27 endrec inc temp2+1 ;Check checksum. +EA68: 261A bne srecerr +EA6A: 0D28 tst temp3 +EA6C: 1027FAE8 lbeq cmdline ;Was it no S9 record? +EA70: 108C0000 cmpy #0 +EA74: 2703 beq endrec1 +EA76: 10AF6A sty 10,s ;Store address into program counter. +EA79: 4F endrec1 clra +EA7A: 5F clrb +EA7B: FD02B0 std sorg ;Reset sorg, next S loads will be normal. +EA7E: FD02B2 std soffs +EA81: 7EE558 jmp cmdline +EA84: 9D18 srecerr jsr xabortin +EA86: 8EE621 ldx #smsg ;Error in srecord, display message. +EA89: BDE4E1 jsr outcount +EA8C: 9D0C jsr putcr +EA8E: 7EE558 jmp cmdline +EA91: BDE70F setsorg jsr scanhex ;Set S record origin. +EA94: FD02B0 std sorg +EA97: 4F clra +EA98: 5F clrb +EA99: FD02B2 std soffs +EA9C: 7EE558 jmp cmdline +EA9F: * Send a memory region as S-records. +EA9F: CC0100 sendrec ldd #$100 ;Scan address and length parameter. +EAA2: BDE732 jsr scan2parms +EAA5: FC02B0 ldd sorg +EAA8: 2709 beq ss1 +EAAA: FC029D ldd addr +EAAD: B302B0 subd sorg +EAB0: FD02B2 std soffs ;Compute offset for origin. +EAB3: FC029F ss1 ldd length +EAB6: 2748 beq endss ;All bytes sent? +EAB8: 10830010 cmpd #16 +EABC: 2502 blo ss2 +EABE: C610 ldb #16 ;If more than 16 left, then send 16. +EAC0: D724 ss2 stb temp +EAC2: 50 negb +EAC3: FE029F ldu length +EAC6: 33C5 leau b,u +EAC8: FF029F stu length ;Discount line length from length. +EACB: C653 ldb #'S' +EACD: 9D03 jsr putchar +EACF: C631 ldb #'1' +EAD1: 9D03 jsr putchar +EAD3: 0F25 clr temp+1 ;Clear check sum +EAD5: D624 ldb temp +EAD7: CB03 addb #3 +EAD9: 8D30 bsr checkout ;Output byte b as hex and add to check sum. +EADB: FC029D ldd addr +EADE: 1F02 tfr d,y +EAE0: B302B2 subd soffs +EAE3: 1E89 exg a,b +EAE5: 8D24 bsr checkout +EAE7: 1E89 exg a,b +EAE9: 8D20 bsr checkout ;Output address (add into check sum) +EAEB: E6A0 ss3 ldb ,y+ +EAED: 8D1C bsr checkout +EAEF: 0A24 dec temp +EAF1: 26F8 bne ss3 +EAF3: 10BF029D sty addr +EAF7: D625 ldb temp+1 +EAF9: 53 comb +EAFA: 8D0F bsr checkout ;Output checksum byte. +EAFC: 9D0C jsr putcr +EAFE: 20B3 bra ss1 +EB00: 8EE633 endss ldx #lastrec +EB03: BDE4E1 jsr outcount +EB06: 9D0C jsr putcr +EB08: 7EE558 jmp cmdline +EB0B: * Output byte in register B and add it into check sum at temp+1 +EB0B: 3402 checkout pshs a +EB0D: 1F98 tfr b,a +EB0F: DB25 addb temp+1 +EB11: D725 stb temp+1 +EB13: BDE6D0 jsr outbyte +EB16: 3502 puls a +EB18: 39 rts +EB19: +EB19: * This is the code for the M command, move memory region. +EB19: * Syntax: Maddr1,addr2,length +EB19: 8E0201 move ldx #linebuf+1 +EB1C: BDE70F jsr scanhex +EB1F: 1027FA91 lbeq unk +EB23: DD28 std temp3 +EB25: BDE6E7 jsr skipspace +EB28: C12C cmpb #',' +EB2A: 1026FA86 lbne unk +EB2E: BDE70F jsr scanhex +EB31: 1027FA7F lbeq unk +EB35: 1F03 tfr d,u +EB37: BDE6E7 jsr skipspace +EB3A: C12C cmpb #',' +EB3C: 1026FA74 lbne unk +EB40: BDE70F jsr scanhex +EB43: 1027FA6D lbeq unk +EB47: 1F02 tfr d,y ;Read the argument separated by commas +EB49: 9E28 ldx temp3 ;src addr to x, dest addr to u, length to y +EB4B: ;Don't tolerate syntax deviations. +EB4B: A680 mvloop lda ,x+ +EB4D: A7C0 sta ,u+ +EB4F: 313F leay -1,y +EB51: 26F8 bne mvloop ;Perform the block move. +EB53: 7EE558 jmp cmdline +EB56: +EB56: +EB56: * This is the code for the F command, find byte/ascii string in memory. +EB56: * Syntax: Faddr bytes or Faddr "ascii" +EB56: 8E0201 find ldx #linebuf+1 +EB59: BDE70F jsr scanhex +EB5C: 1F02 tfr d,y ;Scan the start address. +EB5E: BDE6E7 jsr skipspace +EB61: C122 cmpb #'"' +EB63: 2611 bne findhex +EB65: CE0200 ldu #linebuf ;Quote found, so scan for quoted string. +EB68: 4F clra +EB69: E680 fstrloop ldb ,x+ +EB6B: 271F beq startsrch ;End of line without final quote. +EB6D: C122 cmpb #'"' +EB6F: 271B beq startsrch ;End quote found +EB71: E7C0 stb ,u+ +EB73: 4C inca +EB74: 20F3 bra fstrloop +EB76: CE0200 findhex ldu #linebuf ;Convert string of hex bytes. +EB79: 301F leax -1,x ;String will be stored at start of line +EB7B: 4F clra ;buffer and may overwrite part of the +EB7C: 3402 fhexloop pshs a ;already converted string. +EB7E: BDE74A jsr scanbyte +EB81: 1F89 tfr a,b +EB83: 3502 puls a +EB85: 2705 beq startsrch +EB87: E7C0 stb ,u+ +EB89: 4C inca +EB8A: 20F0 bra fhexloop +EB8C: 4D startsrch tsta ;Start searching, start addr in Y, +EB8D: ;string starts at linebuf, length A +EB8D: 1027F9C7 lbeq cmdline ;Quit with zero length string. +EB91: 0F28 clr temp3 +EB93: 9729 sta temp3+1 +EB95: 1F21 srchloop tfr y,x +EB97: 9629 lda temp3+1 +EB99: 8CE100 cmpx #$e100 +EB9C: 2409 bcc srch1 +EB9E: 3086 leax a,x +EBA0: 8CE000 cmpx #$e000 ;Stop at I/O addresses. +EBA3: 1024F9B1 lbcc cmdline +EBA7: 1F21 srch1 tfr y,x +EBA9: CE0200 ldu #linebuf +EBAC: E680 srch2 ldb ,x+ +EBAE: E1C0 cmpb ,u+ +EBB0: 2614 bne srch3 ;Not equal, try next address. +EBB2: 4A deca +EBB3: 26F7 bne srch2 +EBB5: 1F20 tfr y,d +EBB7: BDE6DE jsr outd ;String found +EBBA: 9D0C jsr putcr +EBBC: 0C28 inc temp3 +EBBE: 9628 lda temp3 +EBC0: 8110 cmpa #$10 +EBC2: 1027F992 lbeq cmdline ;If 10 matches found, just stop. +EBC6: 3121 srch3 leay 1,y +EBC8: 20CB bra srchloop +EBCA: +EBCA: * Send the contents of the xmodem buffer and get it acknowledged, zero flag +EBCA: * is set if transfer aborted. +EBCA: C601 xsendbuf ldb #SOH +EBCC: BDE471 jsr osputc ;Send SOH +EBCF: D62D ldb xpacknum +EBD1: BDE471 jsr osputc ;Send block number. +EBD4: 53 comb +EBD5: BDE471 jsr osputc ;and its complement. +EBD8: 0F2E clr xsum +EBDA: 8680 lda #128 +EBDC: 8E0100 ldx #buf0 +EBDF: E684 xsloop ldb ,x +EBE1: DB2E addb xsum +EBE3: D72E stb xsum +EBE5: E680 ldb ,x+ +EBE7: BDE471 jsr osputc +EBEA: 4A deca +EBEB: 26F2 bne xsloop ;Send the buffer contents. +EBED: D62E ldb xsum +EBEF: BDE471 jsr osputc ;Send the check sum +EBF2: BDE45A waitack jsr osgetc +EBF5: C118 cmpb #CAN +EBF7: 270C beq xsabt ;^X for abort. +EBF9: C115 cmpb #NAK +EBFB: 27CD beq xsendbuf ;Send again if NAK +EBFD: C106 cmpb #ACK +EBFF: 26F1 bne waitack +EC01: 0C2D inc xpacknum +EC03: 1CFB xsok andcc #$fb ;Clear zero flag after ACK +EC05: 39 xsabt rts +EC06: +EC06: * Start an XMODEM send session. +EC06: C601 xsendinit ldb #1 +EC08: D72D stb xpacknum ;Initialize block number. +EC0A: BDE45A waitnak jsr osgetc +EC0D: C118 cmpb #CAN +EC0F: 27F4 beq xsabt ;If ^X exit with zero flag. +EC11: C115 cmpb #NAK +EC13: 27EE beq xsok +EC15: 20F3 bra waitnak ;Wait until NAK received. +EC17: +EC17: * Send ETX and wait for ack. +EC17: C604 xsendeot ldb #EOT +EC19: BDE471 jsr osputc +EC1C: BDE45A waitack2 jsr osgetc +EC1F: C118 cmpb #CAN +EC21: 27E2 beq xsabt +EC23: C115 cmpb #NAK +EC25: 27F0 beq xsendeot +EC27: C106 cmpb #ACK +EC29: 27D8 beq xsok +EC2B: 20EF bra waitack2 +EC2D: +EC2D: * Read character into B with a timeout of A seconds, Carry set if timeout. +EC2D: 48 gettimeout asla +EC2E: 48 asla +EC2F: BDE465 gt1 jsr osgetpoll +EC32: 5D tstb +EC33: 2606 bne gtexit +EC35: 4A deca +EC36: 26F7 bne gt1 +EC38: 1A01 orcc #$1 +EC3A: 39 rts +EC3B: BDE45A gtexit jsr osgetc +EC3E: 1CFE andcc #$fe +EC40: 39 rts +EC41: +EC41: * Wait until line becomes quiet. +EC41: 8603 purge lda #3 +EC43: BDEC2D jsr gettimeout +EC46: 24F9 bcc purge +EC48: 39 rts +EC49: +EC49: * Receive an XMODEM block and wait till it is OK, Z set if etx. +EC49: 8603 xrcvbuf lda #3 +EC4B: 0D2F tst lastok +EC4D: 2709 beq sendnak +EC4F: C606 ldb #ACK +EC51: BDE471 jsr osputc ;Send an ack. +EC54: 860A lda #10 +EC56: 2005 bra startblock +EC58: C615 sendnak ldb #NAK +EC5A: BDE471 jsr osputc ;Send a NAK +EC5D: 0F2F startblock clr lastok +EC5F: 8DCC bsr gettimeout +EC61: 8603 lda #3 +EC63: 25F3 bcs sendnak ;Keep sending NAKs when timed out. +EC65: C104 cmpb #EOT +EC67: 2752 beq xrcveot ;End of file reached, acknowledge EOT. +EC69: C101 cmpb #SOH +EC6B: 2649 bne purgeit ;Not, SOH, bad block. +EC6D: 8601 lda #1 +EC6F: 8DBC bsr gettimeout +EC71: 2543 bcs purgeit +EC73: D12D cmpb xpacknum ;Is it the right block? +EC75: 2707 beq xr1 +EC77: 5C incb +EC78: D12D cmpb xpacknum ;Was it the previous block. +EC7A: 263A bne purgeit +EC7C: 0C2F inc lastok +EC7E: D72E xr1 stb xsum +EC80: 8601 lda #1 +EC82: 8DA9 bsr gettimeout +EC84: 2530 bcs purgeit +EC86: 53 comb +EC87: D12E cmpb xsum ;Is the complement of the block number OK +EC89: 262B bne purgeit +EC8B: 8E0100 ldx #buf0 +EC8E: 0F2E clr xsum +EC90: 8601 xrloop lda #1 +EC92: 8D99 bsr gettimeout +EC94: 2520 bcs purgeit +EC96: E780 stb ,x+ +EC98: DB2E addb xsum +EC9A: D72E stb xsum +EC9C: 8C0180 cmpx #buf0+128 +EC9F: 26EF bne xrloop ;Get the data bytes. +ECA1: 8601 lda #1 +ECA3: 8D88 bsr gettimeout +ECA5: 250F bcs purgeit +ECA7: D12E cmpb xsum +ECA9: 260B bne purgeit ;Check the check sum. +ECAB: 0D2F tst lastok +ECAD: 269A bne xrcvbuf ;Block was the previous block, get next one +ECAF: 0C2F inc lastok +ECB1: 0C2D inc xpacknum +ECB3: 1CFB andcc #$fb +ECB5: 39 rts +ECB6: BDEC41 purgeit jsr purge +ECB9: 209D bra sendnak +ECBB: 8603 xrcveot lda #3 ;EOT was received. +ECBD: C606 ldb #ACK +ECBF: BDE471 ackloop jsr osputc +ECC2: 4A deca +ECC3: 26FA bne ackloop ;Send 3 acks in a row. +ECC5: 39 rts +ECC6: +ECC6: +ECC6: 9E01 savevecs ldx getchar+1 +ECC8: BF02B4 stx oldgetc +ECCB: 9E04 ldx putchar+1 +ECCD: BF02B6 stx oldputc +ECD0: 9E0D ldx putcr+1 +ECD2: BF02B8 stx oldputcr +ECD5: 39 rts +ECD6: +ECD6: BE02B4 rstvecs ldx oldgetc +ECD9: 9F01 stx getchar+1 +ECDB: BE02B6 ldx oldputc +ECDE: 9F04 stx putchar+1 +ECE0: BE02B8 ldx oldputcr +ECE3: 9F0D stx putcr+1 +ECE5: 39 rts +ECE6: +ECE6: * O.S. routine to open input through XMODEM transfer. +ECE6: 3416 xopin pshs x,a,b +ECE8: 8EE63E ldx #xsmsg +ECEB: BDE4E1 jsr outcount +ECEE: 9D0C jsr putcr ;Display message to start XMODEM send. +ECF0: 8DD4 bsr savevecs +ECF2: 8EF434 ldx #noop +ECF5: 9F04 stx putchar+1 ;Disable character output. +ECF7: 8EEDB4 ldx #xgetc +ECFA: 9F01 stx getchar+1 ; +ECFC: 0F2F clr lastok +ECFE: 0F30 clr xcount +ED00: 8601 lda #1 +ED02: 972D sta xpacknum +ED04: 4C inca +ED05: 9731 sta xmode ;set xmode to 2. +ED07: 3596 puls x,a,b,pc +ED09: +ED09: * O.S. routine to open output through XMODEM transfer. +ED09: 3416 xopout pshs x,a,b +ED0B: 8DB9 bsr savevecs +ED0D: 8EE650 ldx #xrmsg +ED10: BDE4E1 jsr outcount ;Display message to start XMODEM receive +ED13: 9D0C jsr putcr +ED15: 8EED7B ldx #xputc +ED18: 9F04 stx putchar+1 +ED1A: 8EED99 ldx #xputcr +ED1D: 9F0D stx putcr+1 +ED1F: BDEC06 jsr xsendinit +ED22: 102700B7 lbeq xerror +ED26: 0F30 clr xcount +ED28: 8601 lda #1 +ED2A: 9731 sta xmode +ED2C: 3596 puls x,a,b,pc +ED2E: +ED2E: +ED2E: * O.S. routine to abort input through XMODEM transfer. +ED2E: 9631 xabtin lda xmode +ED30: 8102 cmpa #2 +ED32: 263C bne xclsend +ED34: BDEC41 jsr purge +ED37: C618 ldb #CAN +ED39: 8608 lda #8 +ED3B: BDE471 xabtloop jsr osputc +ED3E: 4A deca +ED3F: 26FA bne xabtloop ;Send 8 CAN characters to kill transfer. +ED41: 8D93 bsr rstvecs +ED43: 0F31 clr xmode +ED45: 8EE665 ldx #xamsg +ED48: BDE4E1 jsr outcount +ED4B: 9D0C jsr putcr ;Send diagnostic message. +ED4D: 39 rts +ED4E: +ED4E: * O.S. routine to close output through XMODEM transfer. +ED4E: 9631 xclsout lda xmode +ED50: 8101 cmpa #1 +ED52: 261C bne xclsend +ED54: 0D30 tst xcount +ED56: 270C beq xclsdone +ED58: 8680 lda #128 +ED5A: 9030 suba xcount +ED5C: F602BB xclsloop ldb filler +ED5F: 8D1A bsr xputc +ED61: 4A deca +ED62: 26F8 bne xclsloop ;Transfer filler chars to force block out. +ED64: BDEC17 xclsdone jsr xsendeot ;Send EOT +ED67: 10270072 lbeq xerror +ED6B: BDECD6 jsr rstvecs +ED6E: 0F31 clr xmode +ED70: 39 xclsend rts +ED71: +ED71: * O.S. routine to close input through XMODEM, by gobbling up the remaining +ED71: * bytes. +ED71: D631 xclsin ldb xmode +ED73: C102 cmpb #2 +ED75: 26F9 bne xclsend +ED77: 9D03 jsr putchar +ED79: 20F6 bra xclsin +ED7B: +ED7B: * putchar routine for XMODEM +ED7B: 3416 xputc pshs x,a,b +ED7D: 9630 lda xcount +ED7F: 0C30 inc xcount +ED81: 8E0100 ldx #buf0 +ED84: E786 stb a,x ;Store character in XMODEM buffer. +ED86: 817F cmpa #127 +ED88: 260D bne xputc1 ;is buffer full? +ED8A: 0F30 clr xcount +ED8C: 3460 pshs y,u +ED8E: BDEBCA jsr xsendbuf +ED91: 10270048 lbeq xerror +ED95: 3560 puls y,u +ED97: 3596 xputc1 puls x,a,b,pc +ED99: +ED99: * putcr routine for XMODEM +ED99: 3404 xputcr pshs b +ED9B: F602BC ldb xmcr +ED9E: C502 bitb #2 +EDA0: 2704 beq xputcr1 +EDA2: C60D ldb #CR +EDA4: 8DD5 bsr xputc +EDA6: F602BC xputcr1 ldb xmcr +EDA9: C501 bitb #1 +EDAB: 2704 beq xputcr2 +EDAD: C60A ldb #LF +EDAF: 8DCA bsr xputc +EDB1: 3504 xputcr2 puls b +EDB3: 39 rts +EDB4: +EDB4: * getchar routine for XMODEM +EDB4: 3412 xgetc pshs x,a +EDB6: 0D30 tst xcount ;No characters left? +EDB8: 260D bne xgetc1 +EDBA: 3460 pshs y,u +EDBC: BDEC49 jsr xrcvbuf ;Receive new block. +EDBF: 3560 puls y,u +EDC1: 2710 beq xgetcterm ;End of input? +EDC3: 8680 lda #128 +EDC5: 9730 sta xcount +EDC7: 9630 xgetc1 lda xcount +EDC9: 40 nega +EDCA: 8E0180 ldx #buf0+128 +EDCD: E686 ldb a,x ;Get character from buffer +EDCF: 0A30 dec xcount +EDD1: 3592 puls x,a,pc +EDD3: BDECD6 xgetcterm jsr rstvecs +EDD6: 0F31 clr xmode +EDD8: F602BB ldb filler +EDDB: 3592 puls x,a,pc +EDDD: +EDDD: BDECD6 xerror jsr rstvecs ;Restore I/O vectors +EDE0: 0F31 clr xmode +EDE2: 8EE665 ldx #xamsg +EDE5: BDE4E1 jsr outcount +EDE8: 9D0C jsr putcr +EDEA: 7E0292 jmp xerrvec +EDED: +EDED: 10FE02BD xerrhand lds savesp +EDF1: 7EE558 jmp cmdline +EDF4: +EDF4: * This is the code for the X command, various XMODEM related commands. +EDF4: * Syntax: XSaddr,len XLaddr,len XX XOcrlf,filler, XSSaddr,len +EDF4: 8E0201 xmodem ldx #linebuf+1 +EDF7: A680 lda ,x+ +EDF9: 84DF anda #CASEMASK ;Convert to uppercase. +EDFB: 8158 cmpa #'X' +EDFD: 274A beq xeq +EDFF: 814C cmpa #'L' +EE01: 2733 beq xload +EE03: 814F cmpa #'O' +EE05: 2747 beq xopts +EE07: 8153 cmpa #'S' +EE09: 1026F7A7 lbne unk +EE0D: A684 lda ,x +EE0F: 84DF anda #CASEMASK +EE11: 8153 cmpa #'S' +EE13: 271A beq xss +EE15: CC0100 ldd #$100 ;XSaddr,len command. +EE18: BDE732 jsr scan2parms ;Send binary through XMODEM +EE1B: 9D15 jsr xopenout +EE1D: FE029D ldu addr +EE20: 10BE029F ldy length +EE24: E6C0 xsbinloop ldb ,u+ +EE26: 9D03 jsr putchar +EE28: 313F leay -1,y +EE2A: 26F8 bne xsbinloop ;Send all the bytes through XMODEM. +EE2C: 7EE558 jmp cmdline +EE2F: 3001 xss leax 1,x ;XSSaddr,len command. +EE31: 9D15 jsr xopenout ;Send Srecords through XMODEM +EE33: 7EEA9F jmp sendrec +EE36: BDE70F xload jsr scanhex ;XLaddr command +EE39: 1F02 tfr d,y ;Load binary through XMODEM +EE3B: 9D12 jsr xopenin +EE3D: 9D00 xlodloop jsr getchar +EE3F: 0D31 tst xmode ;File ended? then done +EE41: 1027F713 lbeq cmdline +EE45: E7A0 stb ,y+ +EE47: 20F4 bra xlodloop +EE49: 9D12 xeq jsr xopenin ;XX command +EE4B: 7EE558 jmp cmdline ;Execute commands received from XMODEM +EE4E: CC001A xopts ldd #$1a +EE51: BDE732 jsr scan2parms +EE54: B6029E lda addr+1 +EE57: B702BC sta xmcr +EE5A: B602A0 lda length+1 +EE5D: B702BB sta filler +EE60: 7EE558 jmp cmdline +EE63: +EE63: * mnemonics table, ordered alphabetically. +EE63: * 5 bytes name, 1 byte category, 2 bytes opcode, 8 bytes total. +EE63: 4142582020 mnemtab fcc "ABX " +EE68: 00 fcb 0 +EE69: 003A fdb $3a +EE6B: 4144434120 fcc "ADCA " +EE70: 07 fcb 7 +EE71: 0089 fdb $89 +EE73: 4144434220 fcc "ADCB " +EE78: 07 fcb 7 +EE79: 00C9 fdb $c9 +EE7B: 4144444120 fcc "ADDA " +EE80: 07 fcb 7 +EE81: 008B fdb $8b +EE83: 4144444220 fcc "ADDB " +EE88: 07 fcb 7 +EE89: 00CB fdb $cb +EE8B: 4144444420 fcc "ADDD " +EE90: 08 fcb 8 +EE91: 00C3 fdb $c3 +EE93: 414E444120 fcc "ANDA " +EE98: 07 fcb 7 +EE99: 0084 fdb $84 +EE9B: 414E444220 fcc "ANDB " +EEA0: 07 fcb 7 +EEA1: 00C4 fdb $c4 +EEA3: 414E444343 fcc "ANDCC" +EEA8: 02 fcb 2 +EEA9: 001C fdb $1c +EEAB: 41534C2020 fcc "ASL " +EEB0: 0A fcb 10 +EEB1: 0008 fdb $08 +EEB3: 41534C4120 fcc "ASLA " +EEB8: 00 fcb 0 +EEB9: 0048 fdb $48 +EEBB: 41534C4220 fcc "ASLB " +EEC0: 00 fcb 0 +EEC1: 0058 fdb $58 +EEC3: 4153522020 fcc "ASR " +EEC8: 0A fcb 10 +EEC9: 0007 fdb $07 +EECB: 4153524120 fcc "ASRA " +EED0: 00 fcb 0 +EED1: 0047 fdb $47 +EED3: 4153524220 fcc "ASRB " +EED8: 00 fcb 0 +EED9: 0057 fdb $57 +EEDB: 4243432020 fcc "BCC " +EEE0: 04 fcb 4 +EEE1: 0024 fdb $24 +EEE3: 4243532020 fcc "BCS " +EEE8: 04 fcb 4 +EEE9: 0025 fdb $25 +EEEB: 4245512020 fcc "BEQ " +EEF0: 04 fcb 4 +EEF1: 0027 fdb $27 +EEF3: 4247452020 fcc "BGE " +EEF8: 04 fcb 4 +EEF9: 002C fdb $2c +EEFB: 4247542020 fcc "BGT " +EF00: 04 fcb 4 +EF01: 002E fdb $2e +EF03: 4248492020 fcc "BHI " +EF08: 04 fcb 4 +EF09: 0022 fdb $22 +EF0B: 4248532020 fcc "BHS " +EF10: 04 fcb 4 +EF11: 0024 fdb $24 +EF13: 4249544120 fcc "BITA " +EF18: 07 fcb 7 +EF19: 0085 fdb $85 +EF1B: 4249544220 fcc "BITB " +EF20: 07 fcb 7 +EF21: 00C5 fdb $c5 +EF23: 424C452020 fcc "BLE " +EF28: 04 fcb 4 +EF29: 002F fdb $2f +EF2B: 424C4F2020 fcc "BLO " +EF30: 04 fcb 4 +EF31: 0025 fdb $25 +EF33: 424C532020 fcc "BLS " +EF38: 04 fcb 4 +EF39: 0023 fdb $23 +EF3B: 424C542020 fcc "BLT " +EF40: 04 fcb 4 +EF41: 002D fdb $2d +EF43: 424D492020 fcc "BMI " +EF48: 04 fcb 4 +EF49: 002B fdb $2b +EF4B: 424E452020 fcc "BNE " +EF50: 04 fcb 4 +EF51: 0026 fdb $26 +EF53: 42504C2020 fcc "BPL " +EF58: 04 fcb 4 +EF59: 002A fdb $2a +EF5B: 4252412020 fcc "BRA " +EF60: 04 fcb 4 +EF61: 0020 fdb $20 +EF63: 42524E2020 fcc "BRN " +EF68: 04 fcb 4 +EF69: 0021 fdb $21 +EF6B: 4253522020 mnembsr fcc "BSR " +EF70: 04 fcb 4 +EF71: 008D fdb $8d +EF73: 4256432020 fcc "BVC " +EF78: 04 fcb 4 +EF79: 0028 fdb $28 +EF7B: 4256532020 fcc "BVS " +EF80: 04 fcb 4 +EF81: 0029 fdb $29 +EF83: 434C522020 fcc "CLR " +EF88: 0A fcb 10 +EF89: 000F fdb $0f +EF8B: 434C524120 fcc "CLRA " +EF90: 00 fcb 0 +EF91: 004F fdb $4f +EF93: 434C524220 fcc "CLRB " +EF98: 00 fcb 0 +EF99: 005F fdb $5f +EF9B: 434D504120 fcc "CMPA " +EFA0: 07 fcb 7 +EFA1: 0081 fdb $81 +EFA3: 434D504220 fcc "CMPB " +EFA8: 07 fcb 7 +EFA9: 00C1 fdb $c1 +EFAB: 434D504420 fcc "CMPD " +EFB0: 09 fcb 9 +EFB1: 1083 fdb $1083 +EFB3: 434D505320 fcc "CMPS " +EFB8: 09 fcb 9 +EFB9: 118C fdb $118c +EFBB: 434D505520 fcc "CMPU " +EFC0: 09 fcb 9 +EFC1: 1183 fdb $1183 +EFC3: 434D505820 fcc "CMPX " +EFC8: 08 fcb 8 +EFC9: 008C fdb $8c +EFCB: 434D505920 fcc "CMPY " +EFD0: 09 fcb 9 +EFD1: 108C fdb $108c +EFD3: 434F4D2020 fcc "COM " +EFD8: 0A fcb 10 +EFD9: 0003 fdb $03 +EFDB: 434F4D4120 fcc "COMA " +EFE0: 00 fcb 0 +EFE1: 0043 fdb $43 +EFE3: 434F4D4220 fcc "COMB " +EFE8: 00 fcb 0 +EFE9: 0053 fdb $53 +EFEB: 4357414920 fcc "CWAI " +EFF0: 02 fcb 2 +EFF1: 003C fdb $3c +EFF3: 4441412020 fcc "DAA " +EFF8: 00 fcb 0 +EFF9: 0019 fdb $19 +EFFB: 4445432020 fcc "DEC " +F000: 0A fcb 10 +F001: 000A fdb $0a +F003: 4445434120 fcc "DECA " +F008: 00 fcb 0 +F009: 004A fdb $4a +F00B: 4445434220 fcc "DECB " +F010: 00 fcb 0 +F011: 005A fdb $5a +F013: 454F524120 fcc "EORA " +F018: 07 fcb 7 +F019: 0088 fdb $88 +F01B: 454F524220 fcc "EORB " +F020: 07 fcb 7 +F021: 00C8 fdb $c8 +F023: 4551552020 fcc "EQU " +F028: 0D fcb 13 +F029: 0005 fdb 5 +F02B: 4558472020 fcc "EXG " +F030: 0B fcb 11 +F031: 001E fdb $1e +F033: 4643422020 mnemfcb fcc "FCB " +F038: 0D fcb 13 +F039: 0007 fdb 7 +F03B: 4643432020 fcc "FCC " +F040: 0D fcb 13 +F041: 0008 fdb 8 +F043: 4644422020 fcc "FDB " +F048: 0D fcb 13 +F049: 0009 fdb 9 +F04B: 494E432020 fcc "INC " +F050: 0A fcb 10 +F051: 000C fdb $0c +F053: 494E434120 fcc "INCA " +F058: 00 fcb 0 +F059: 004C fdb $4c +F05B: 494E434220 fcc "INCB " +F060: 00 fcb 0 +F061: 005C fdb $5c +F063: 4A4D502020 fcc "JMP " +F068: 0A fcb 10 +F069: 000E fdb $0e +F06B: 4A53522020 mnemjsr fcc "JSR " +F070: 08 fcb 8 +F071: 008D fdb $8d +F073: 4C42434320 fcc "LBCC " +F078: 05 fcb 5 +F079: 1024 fdb $1024 +F07B: 4C42435320 fcc "LBCS " +F080: 05 fcb 5 +F081: 1025 fdb $1025 +F083: 4C42455120 fcc "LBEQ " +F088: 05 fcb 5 +F089: 1027 fdb $1027 +F08B: 4C42474520 fcc "LBGE " +F090: 05 fcb 5 +F091: 102C fdb $102c +F093: 4C42475420 fcc "LBGT " +F098: 05 fcb 5 +F099: 102E fdb $102e +F09B: 4C42484920 fcc "LBHI " +F0A0: 05 fcb 5 +F0A1: 1022 fdb $1022 +F0A3: 4C42485320 fcc "LBHS " +F0A8: 05 fcb 5 +F0A9: 1024 fdb $1024 +F0AB: 4C424C4520 fcc "LBLE " +F0B0: 05 fcb 5 +F0B1: 102F fdb $102f +F0B3: 4C424C4F20 fcc "LBLO " +F0B8: 05 fcb 5 +F0B9: 1025 fdb $1025 +F0BB: 4C424C5320 fcc "LBLS " +F0C0: 05 fcb 5 +F0C1: 1023 fdb $1023 +F0C3: 4C424C5420 fcc "LBLT " +F0C8: 05 fcb 5 +F0C9: 102D fdb $102d +F0CB: 4C424D4920 fcc "LBMI " +F0D0: 05 fcb 5 +F0D1: 102B fdb $102b +F0D3: 4C424E4520 fcc "LBNE " +F0D8: 05 fcb 5 +F0D9: 1026 fdb $1026 +F0DB: 4C42504C20 fcc "LBPL " +F0E0: 05 fcb 5 +F0E1: 102A fdb $102a +F0E3: 4C42524120 fcc "LBRA " +F0E8: 06 fcb 6 +F0E9: 0016 fdb $16 +F0EB: 4C42524E20 fcc "LBRN " +F0F0: 05 fcb 5 +F0F1: 1021 fdb $1021 +F0F3: 4C42535220 fcc "LBSR " +F0F8: 06 fcb 6 +F0F9: 0017 fdb $17 +F0FB: 4C42564320 fcc "LBVC " +F100: 05 fcb 5 +F101: 1028 fdb $1028 +F103: 4C42565320 fcc "LBVS " +F108: 05 fcb 5 +F109: 1029 fdb $1029 +F10B: 4C44412020 fcc "LDA " +F110: 07 fcb 7 +F111: 0086 fdb $86 +F113: 4C44422020 fcc "LDB " +F118: 07 fcb 7 +F119: 00C6 fdb $c6 +F11B: 4C44442020 fcc "LDD " +F120: 08 fcb 8 +F121: 00CC fdb $cc +F123: 4C44532020 fcc "LDS " +F128: 09 fcb 9 +F129: 10CE fdb $10ce +F12B: 4C44552020 fcc "LDU " +F130: 08 fcb 8 +F131: 00CE fdb $ce +F133: 4C44582020 fcc "LDX " +F138: 08 fcb 8 +F139: 008E fdb $8e +F13B: 4C44592020 fcc "LDY " +F140: 09 fcb 9 +F141: 108E fdb $108e +F143: 4C45415320 fcc "LEAS " +F148: 03 fcb 3 +F149: 0032 fdb $32 +F14B: 4C45415520 fcc "LEAU " +F150: 03 fcb 3 +F151: 0033 fdb $33 +F153: 4C45415820 fcc "LEAX " +F158: 03 fcb 3 +F159: 0030 fdb $30 +F15B: 4C45415920 fcc "LEAY " +F160: 03 fcb 3 +F161: 0031 fdb $31 +F163: 4C534C2020 fcc "LSL " +F168: 0A fcb 10 +F169: 0008 fdb $08 +F16B: 4C534C4120 fcc "LSLA " +F170: 00 fcb 0 +F171: 0048 fdb $48 +F173: 4C534C4220 fcc "LSLB " +F178: 00 fcb 0 +F179: 0058 fdb $58 +F17B: 4C53522020 fcc "LSR " +F180: 0A fcb 10 +F181: 0004 fdb $04 +F183: 4C53524120 fcc "LSRA " +F188: 00 fcb 0 +F189: 0044 fdb $44 +F18B: 4C53524220 fcc "LSRB " +F190: 00 fcb 0 +F191: 0054 fdb $54 +F193: 4D554C2020 fcc "MUL " +F198: 00 fcb 0 +F199: 003D fdb $3d +F19B: 4E45472020 fcc "NEG " +F1A0: 0A fcb 10 +F1A1: 0000 fdb $00 +F1A3: 4E45474120 fcc "NEGA " +F1A8: 00 fcb 0 +F1A9: 0040 fdb $40 +F1AB: 4E45474220 fcc "NEGB " +F1B0: 00 fcb 0 +F1B1: 0050 fdb $50 +F1B3: 4E4F502020 fcc "NOP " +F1B8: 00 fcb 0 +F1B9: 0012 fdb $12 +F1BB: 4F52412020 fcc "ORA " +F1C0: 07 fcb 7 +F1C1: 008A fdb $8a +F1C3: 4F52422020 fcc "ORB " +F1C8: 07 fcb 7 +F1C9: 00CA fdb $ca +F1CB: 4F52434320 fcc "ORCC " +F1D0: 02 fcb 2 +F1D1: 001A fdb $1a +F1D3: 4F52472020 fcc "ORG " +F1D8: 0D fcb 13 +F1D9: 000C fdb 12 +F1DB: 5053485320 fcc "PSHS " +F1E0: 0C fcb 12 +F1E1: 0034 fdb $34 +F1E3: 5053485520 fcc "PSHU " +F1E8: 0C fcb 12 +F1E9: 0036 fdb $36 +F1EB: 50554C5320 fcc "PULS " +F1F0: 0C fcb 12 +F1F1: 0035 fdb $35 +F1F3: 50554C5520 fcc "PULU " +F1F8: 0C fcb 12 +F1F9: 0037 fdb $37 +F1FB: 524D422020 fcc "RMB " +F200: 0D fcb 13 +F201: 0000 fdb 0 +F203: 524F4C2020 fcc "ROL " +F208: 0A fcb 10 +F209: 0009 fdb $09 +F20B: 524F4C4120 fcc "ROLA " +F210: 00 fcb 0 +F211: 0049 fdb $49 +F213: 524F4C4220 fcc "ROLB " +F218: 00 fcb 0 +F219: 0059 fdb $59 +F21B: 524F522020 fcc "ROR " +F220: 0A fcb 10 +F221: 0006 fdb $06 +F223: 524F524120 fcc "RORA " +F228: 00 fcb 0 +F229: 0046 fdb $46 +F22B: 524F524220 fcc "RORB " +F230: 00 fcb 0 +F231: 0056 fdb $56 +F233: 5254492020 fcc "RTI " +F238: 00 fcb 0 +F239: 003B fdb $3b +F23B: 5254532020 fcc "RTS " +F240: 00 fcb 0 +F241: 0039 fdb $39 +F243: 5342434120 fcc "SBCA " +F248: 07 fcb 7 +F249: 0082 fdb $82 +F24B: 5342434220 fcc "SBCB " +F250: 07 fcb 7 +F251: 00C2 fdb $c2 +F253: 5345542020 fcc "SET " +F258: 0D fcb 13 +F259: 000F fdb 15 +F25B: 5345544450 fcc "SETDP" +F260: 0D fcb 13 +F261: 000E fdb 14 +F263: 5345582020 fcc "SEX " +F268: 00 fcb 0 +F269: 001D fdb $1d +F26B: 5354412020 fcc "STA " +F270: 07 fcb 7 +F271: 0087 fdb $87 +F273: 5354422020 fcc "STB " +F278: 07 fcb 7 +F279: 00C7 fdb $c7 +F27B: 5354442020 fcc "STD " +F280: 08 fcb 8 +F281: 00CD fdb $cd +F283: 5354532020 fcc "STS " +F288: 09 fcb 9 +F289: 10CF fdb $10cf +F28B: 5354552020 fcc "STU " +F290: 08 fcb 8 +F291: 00CF fdb $cf +F293: 5354582020 fcc "STX " +F298: 08 fcb 8 +F299: 008F fdb $8f +F29B: 5354592020 fcc "STY " +F2A0: 09 fcb 9 +F2A1: 108F fdb $108f +F2A3: 5355424120 fcc "SUBA " +F2A8: 07 fcb 7 +F2A9: 0080 fdb $80 +F2AB: 5355424220 fcc "SUBB " +F2B0: 07 fcb 7 +F2B1: 00C0 fdb $c0 +F2B3: 5355424420 fcc "SUBD " +F2B8: 08 fcb 8 +F2B9: 0083 fdb $83 +F2BB: 5357492020 fcc "SWI " +F2C0: 00 fcb 0 +F2C1: 003F fdb $3f +F2C3: 5357493220 fcb "SWI2 " +F2C8: 01 fcb 1 +F2C9: 103F fdb $103f +F2CB: 5357493320 fcb "SWI3 " +F2D0: 01 fcb 1 +F2D1: 113F fdb $113f +F2D3: 53594E4320 fcc "SYNC " +F2D8: 00 fcb 0 +F2D9: 0013 fdb $13 +F2DB: 5446522020 fcc "TFR " +F2E0: 0B fcb 11 +F2E1: 001F fdb $1f +F2E3: 5453542020 fcc "TST " +F2E8: 0A fcb 10 +F2E9: 000D fdb $0d +F2EB: 5453544120 fcc "TSTA " +F2F0: 00 fcb 0 +F2F1: 004D fdb $4d +F2F3: 5453544220 fcc "TSTB " +F2F8: 00 fcb 0 +F2F9: 005D fdb $5d +F2FB: +F2FB: mnemsize equ (*-mnemtab)/8 +F2FB: +F2FB: * Register table for PUSH/PULL and TFR/EXG instructions. +F2FB: * 3 bytes for name, 1 for tfr/exg, 1 for push/pull, 5 total +F2FB: 582020 asmregtab fcc "X " +F2FE: 0110 fcb $01,$10 +F300: 592020 fcc "Y " +F303: 0220 fcb $02,$20 +F305: 552020 aregu fcc "U " +F308: 0340 fcb $03,$40 +F30A: 532020 aregs fcc "S " +F30D: 0440 fcb $04,$40 +F30F: 504320 fcc "PC " +F312: 0580 fcb $05,$80 +F314: 412020 fcc "A " +F317: 0802 fcb $08,$02 +F319: 422020 fcc "B " +F31C: 0904 fcb $09,$04 +F31E: 442020 fcc "D " +F321: 0006 fcb $00,$06 +F323: 434320 fcc "CC " +F326: 0A01 fcb $0a,$01 +F328: 434352 fcc "CCR" +F32B: 0A01 fcb $0a,$01 +F32D: 445020 fcc "DP " +F330: 0B08 fcb $0b,$08 +F332: 445052 fcc "DPR" +F335: 0B08 fcb $0b,$08 +F337: 3F2020 reginval fcc "? " +F33A: +F33A: 58595553 ixregs fcc "XYUS" +F33E: +F33E: * opcode offsets to basic opcode, depends on first nibble. +F33E: 000000000000A0 opcoffs fcb 0,0,0,0,0,0,-$60,-$70 +F346: 00F0E0D000F0E0 fcb 0,-$10,-$20,-$30,0,-$10,-$20,-$30 +F34E: * mode depending on first nibble of opcode. +F34E: 03000000000005 modetab fcb 3,0,0,0,0,0,5,4,1,3,5,4,1,3,5,4 +F35E: * mode depending on category code stored in mnemtab +F35E: 00000105060707 modetab2 fcb 0,0,1,5,6,7,7,1,2,2,0,8,9 +F36B: * modes in this context: 0 no operands, 1 8-bit immediate, 2 16 bit imm, +F36B: * 3, 8-bit address, 4 16 bit address, 5 indexed with postbyte, 6 short +F36B: * relative, 7 long relative, 8 pushpul, 9 tftetx +F36B: +F36B: * Decode instruction pointed to by Y for disassembly (and to find out +F36B: * how long it is). On return, U points to appropriate mnemonic table entry, +F36B: * Y points past instruction. +F36B: * It's rather clumsy code, but we do want to reuse the same table +F36B: * as used with assembling. +F36B: 7F02BF disdecode clr prebyte +F36E: 7F02C3 clr amode +F371: A6A0 lda ,y+ +F373: 8110 cmpa #$10 +F375: 2704 beq ddec1 +F377: 8111 cmpa #$11 +F379: 2605 bne ddec2 +F37B: B702BF ddec1 sta prebyte ;Store $10 or $11 prebyte. +F37E: A6A0 lda ,y+ ;Get new opcode. +F380: B702C1 ddec2 sta opcode +F383: 44 lsra +F384: 44 lsra +F385: 44 lsra +F386: 44 lsra ;Get high nibble. +F387: 8EF34E ldx #modetab +F38A: E686 ldb a,x +F38C: F702C3 stb amode +F38F: 8EF33E ldx #opcoffs +F392: A686 lda a,x +F394: BB02C1 adda opcode ;Add opcode offset to opcode. +F397: B702C0 ddec4 sta opc1 ;Store the 'basis' opcode. +F39A: CEEE63 ldu #mnemtab +F39D: 8E0093 ldx #mnemsize +F3A0: C60D ddecloop ldb #13 +F3A2: E145 cmpb 5,u ;Compare category code with 13 +F3A4: 2708 beq ddec3 ;13=pseudo op, no valid opcode +F3A6: FC02BF ldd prebyte +F3A9: 10A346 cmpd 6,u +F3AC: 2722 beq ddecfound ;Opcode&prebyte agree, operation found. +F3AE: 3348 ddec3 leau 8,u ;point to next mnemonic +F3B0: 301F leax -1,x +F3B2: 26EC bne ddecloop +F3B4: CEF033 ldu #mnemfcb ;mnemonic not found, use FCB byte. +F3B7: 8603 lda #3 +F3B9: B702C3 sta amode ;Store mode 3, 8 bit address. +F3BC: B602C1 lda opcode +F3BF: 7D02BF tst prebyte +F3C2: 2708 beq ddec5 +F3C4: B602BF lda prebyte ;if it was the combination prebyte +F3C7: 7F02BF clr prebyte ;and opcode that was not found, +F3CA: 313F leay -1,y ;FCB just the prebyte +F3CC: B702C5 ddec5 sta operand+1 ;The byte must be stored as operand. +F3CF: 39 rts +F3D0: 1183EF6B ddecfound cmpu #mnembsr +F3D4: 260A bne ddec6 +F3D6: 868D lda #$8d ;Is it really the BSR opcode? +F3D8: B102C1 cmpa opcode +F3DB: 2703 beq ddec6 +F3DD: CEF06B ldu #mnemjsr ;We mistakenly found BSR instead of JSR +F3E0: B602C3 ddec6 lda amode +F3E3: 84FE anda #$FE +F3E5: 260A bne ddec7 +F3E7: A645 lda 5,u ;nibble-dependent mode was 0 or 1, +F3E9: 8EF35E ldx #modetab2 ;use category dependent mode instead. +F3EC: A686 lda a,x +F3EE: B702C3 sta amode +F3F1: B602C3 ddec7 lda amode +F3F4: 48 asla +F3F5: 8EF3FA ldx #disdectab +F3F8: 6E96 jmp [a,x] ;jump dependent on definitive mode. +F3FA: F434F42EF435F4 disdectab fdb noop,opdec1,opdec2,opdec1,opdec2,opdecidx +F406: F42EF435F439F4 fdb opdec1,opdec2,opdecpb,opdecpb +F40E: F434F434F434F4 disdectab1 fdb noop,noop,noop,noop,noop,noop,noop,noop +F41E: F42EF435F434F4 fdb opdec1,opdec2,noop,noop,opdec1,opdec2,noop,opdec2 +F42E: E6A0 opdec1 ldb ,y+ +F430: 1D sex +F431: FD02C4 od1a std operand +F434: 39 noop rts +F435: ECA1 opdec2 ldd ,y++ +F437: 20F8 bra od1a +F439: E6A0 opdecpb ldb ,y+ +F43B: F702C2 odpa stb postbyte +F43E: 39 rts +F43F: E6A0 opdecidx ldb ,y+ +F441: 2AF8 bpl odpa ;postbytes <$80 have no extra operands. +F443: F702C2 stb postbyte +F446: C40F andb #$0f +F448: 58 aslb +F449: 8EF40E ldx #disdectab1 +F44C: 6E95 jmp [b,x] +F44E: +F44E: * Display disassembled instruction after the invocation of disdecode. +F44E: * U points to mnemonic table entry. +F44E: 1F31 disdisp tfr u,x +F450: C605 ldb #5 +F452: 9D09 jsr putline ;Display the mnemonic. +F454: C620 ldb #' ' +F456: 9D03 jsr putchar +F458: B602C3 lda amode +F45B: 48 asla +F45C: 8EF461 ldx #disdisptab +F45F: 6E96 jmp [a,x] ;Perform action dependent on mode. +F461: F434F475F479F4 disdisptab fdb noop,disim8,disim16,disadr8,disadr16 +F46B: F53BF48BF499F4 fdb disidx,disrel8,disrel16,distfr,dispush +F475: 8D29 disim8 bsr puthash +F477: 200A bra disadr8 +F479: 8D25 disim16 bsr puthash +F47B: 8D27 disadr16 bsr putdol +F47D: FC02C4 ldd operand +F480: 7EE6DE jmp outd +F483: 8D1F disadr8 bsr putdol +F485: B602C5 lda operand+1 +F488: 7EE6D0 jmp outbyte +F48B: 8D17 disrel8 bsr putdol +F48D: F602C5 ldb operand+1 +F490: 1D sex