diff --git a/Doc/ChangeLog.txt b/Doc/ChangeLog.txt
index b225da0d..610fb134 100644
--- a/Doc/ChangeLog.txt
+++ b/Doc/ChangeLog.txt
@@ -11,6 +11,8 @@ Version 2.9.2
- WBW: Add RC2014 AY sound support to AY driver
- WBW: Add SC126 platform
- WBW: Config files cleanup
+- WBW: Add interrupt support to ASCI driver
+- WBW: Refactored XModem overlay, merged USB-FIFO support
Version 2.9.1
-------------
diff --git a/Source/Apps/Build.cmd b/Source/Apps/Build.cmd
index 67bffb0a..f3d58557 100644
--- a/Source/Apps/Build.cmd
+++ b/Source/Apps/Build.cmd
@@ -30,6 +30,7 @@ zx MLOAD25 -SURVEY.COM=SURVEY.HEX
setlocal & cd XM && call Build || exit /b 1 & endlocal
setlocal & cd FDU && call Build || exit /b 1 & endlocal
setlocal & cd Tune && call Build || exit /b 1 & endlocal
+setlocal & cd FAT && call Build || exit /b 1 & endlocal
copy *.com %APPBIN%\
diff --git a/Source/Apps/Clean.cmd b/Source/Apps/Clean.cmd
index 66bb9407..70b6dcee 100644
--- a/Source/Apps/Clean.cmd
+++ b/Source/Apps/Clean.cmd
@@ -10,3 +10,4 @@ if exist *.prn del *.prn
setlocal & cd XM && call Clean || exit /b 1 & endlocal
setlocal & cd FDU && call Clean || exit /b 1 & endlocal
setlocal & cd Tune && call Clean || exit /b 1 & endlocal
+setlocal & cd FAT && call Clean || exit /b 1 & endlocal
diff --git a/Source/Apps/FAT/Build.cmd b/Source/Apps/FAT/Build.cmd
new file mode 100644
index 00000000..34e25577
--- /dev/null
+++ b/Source/Apps/FAT/Build.cmd
@@ -0,0 +1,7 @@
+@echo off
+setlocal
+
+REM FAT.com is currently distributed as a binary application, so
+REM it is not built here.
+
+copy /Y FAT.com ..\..\..\Binary\Apps\
diff --git a/Source/Apps/FAT/Clean.cmd b/Source/Apps/FAT/Clean.cmd
new file mode 100644
index 00000000..01cc66c3
--- /dev/null
+++ b/Source/Apps/FAT/Clean.cmd
@@ -0,0 +1,5 @@
+@echo off
+setlocal
+
+REM FAT.com is currently distributed as a binary application, so
+REM we do not delete the .COM file.
\ No newline at end of file
diff --git a/Source/Apps/FAT/FAT.COM b/Source/Apps/FAT/FAT.COM
new file mode 100644
index 00000000..4bd4cc70
Binary files /dev/null and b/Source/Apps/FAT/FAT.COM differ
diff --git a/Source/Apps/FAT/LICENSE.txt b/Source/Apps/FAT/LICENSE.txt
new file mode 100644
index 00000000..818433ec
--- /dev/null
+++ b/Source/Apps/FAT/LICENSE.txt
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. 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
+them 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 prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. 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.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey 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;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU 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 that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ 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.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+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.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ 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
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ 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 3 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, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program 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, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU 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. But first, please read
+.
diff --git a/Source/Apps/FAT/ReadMe.txt b/Source/Apps/FAT/ReadMe.txt
new file mode 100644
index 00000000..e3c60813
--- /dev/null
+++ b/Source/Apps/FAT/ReadMe.txt
@@ -0,0 +1,94 @@
+RomWBW HBIOS CP/M FAT Utility ("FAT.COM")
+
+Author: Wayne Warthen
+Updated: 8-May-2019
+
+Application to manipulate and exchange files with a FAT (DOS)
+filesystem. Runs on any HBIOS hosted CP/M implementation.
+
+USAGE:
+ FAT DIR
+ FAT COPY
+ FAT REN
+ FAT DEL
+
+ CP/M filespec: :FILENAME.EXT ( is CP/M drive letter A-P)
+ FAT filespec: :/DIR/FILENAME.EXT ( is disk unit #)
+
+LICENSE:
+ GNU GPLv3 (see file LICENSE.txt)
+
+NOTES:
+ - Partitioned or non-partitioned media is handled automatically.
+ A floppy drive is a good example of a non-partitioned FAT
+ filesystem and will be recognized. Larger media will typically
+ have a partition table which will be recognized by the
+ application to find the FAT filesystem.
+
+ - Although RomWBW-style CP/M media does not know anything about
+ partition tables, it is entirely possible to have media that
+ has both CP/M and FAT file systems on it. This is accomplished
+ by creating a FAT filesystem on the media that starts on a track
+ beyond the last track used by CP/M. Each CP/M slice on a
+ media will occupy a little over 8MB. So, make sure to start
+ your FAT partition beyond (slice count) * 8MB.
+
+ - The application infers whether you are attempting to reference
+ a FAT or CP/M filesystem via the drive specifier (char before ':').
+ A numeric drive character specifies the HBIOS disk unit number
+ for FAT access. An alpha (A-P) character indicates a CP/M
+ file system access targeting the specified drive letter. If there
+ is no drive character specified, the current CP/M filesystem and
+ current CP/M drive is assumed. For example:
+
+ "2:README.TXT" refers to FAT file README.TXT on disk unit #2
+ "C:README.TXT" refers to CP/M file README.TXT on CP/M drive C
+ "README.TXT" refers to CP/M file README.TXT on current CP/M drive
+
+ - Files with SYS, HIDDEN, or R/O only attributes are not given
+ any special treatment. Such files are found and processed
+ like any other file. However, any attempt to write to a
+ read-only file will fail and the application will abort.
+
+ - It is not currently possible to reference CP/M user areas other
+ than the current user. To copy files to alternate user areas,
+ you must switch to the desired user number first or use an
+ additional step to copy the file to the desired user area.
+
+ - Accessing FAT filesystems on a floppy requires the use of
+ RomWBW HBIOS v2.9.1-pre.13 or greater.
+
+ - Files written are not verified.
+
+ - Wildcard matching in FAT filesystems is a bit unusual as
+ implemented by FatFS. See FatFS documentation.
+
+BUILD NOTES:
+ - Source is maintained on GitHub at https://github.com/wwarthen/FAT
+
+ - Application is based on FatFS. FatFS source is included.
+
+ - SDCC compiler is required to build (v3.9.0 known working).
+
+ - ZX CP/M emulator is required to build (from RomWBW distribution).
+
+ - See Build.cmd for sample build script under Windows. References
+ to SDCC and ZX must be updated for your environment.
+
+ - Note that ff.c (core FatFS code) gneerates quite a few compiler
+ warnings (all appear to be benign).
+
+TO DO:
+ - Confirm HBIOS is present at startup.
+
+ - Allow ^C to abort any operation in progress.
+
+ - Handle wildcards in destination, i.e.:
+ "FAT REN 2:/*.TXT 2:/*.BAK"
+
+ - Do something intelligent with R/O and SYS files
+
+HISTORY:
+ 2-May-2019: v0.9 initial release (beta)
+ 7-May-2019: v0.9.1 added REN and DEL (beta)
+ 8-May-2019: v0.9.2 handle file collisions w/ user prompt (beta)
diff --git a/Source/Apps/XM/xmhb.180 b/Source/Apps/XM/xmhb.180
index b97886b5..7e33e4ac 100644
--- a/Source/Apps/XM/xmhb.180
+++ b/Source/Apps/XM/xmhb.180
@@ -1,19 +1,14 @@
;=======================================================================
;
-; XMHB.Z80 - XMODEMXX PATCH FILE FOR ROMWBW HBIOS
+; XMHB.Z80 - XMODEM12 PATCH FILE FOR ROMWBW HBIOS
;
; Wayne Warthen - wwarthen@gmail.com
-; Updated: 2018-06-06
;
; 2018-06-06 WBW Added support for RC2014 w/ Z180
+; 2019-08-17 WBW Refactored and merged Phil's ECB-FIFO support
;
;=======================================================================
;
-; Overlay file is Z80, build with M80:
-; M80 =XMHB
-; L80 XMHB,XMHB/N/X/E
-;
- .Z80
ASEG
;
NO EQU 0
@@ -31,22 +26,22 @@ BDOS EQU 00005H ; BDOS function dispatch vector
; one in XMODEM. Note the ORG of 103H - This jump table has no jump to
; 'BEGIN'.
;
- ORG BASE + 3 ;start after 'JMP BEGIN'
+ ORG BASE + 3 ; start after 'JMP BEGIN'
;
- JP CONOUT ;must be 00000h if not used, see below
- JP MINIT ;initialization routine (if needed)
- JP UNINIT ;undo whatever 'MINIT' did (or return)
+ JP CONOUT ; must be 00000h if not used, see below
+ JP MINIT ; initialization routine (if needed)
+ JP UNINIT ; undo whatever 'MINIT' did (or return)
JPTBL:
- JP SENDR ;send character (via pop psw)
- JP CAROK ;test for carrier
- JP MDIN ;receive data byte
- JP GETCHR ;get character from modem
- JP RCVRDY ;check receive ready
- JP SNDRDY ;check send ready
- JP SPEED ;get speed value for file transfer time
- JP EXTRA1 ;extra for custom routine
- JP EXTRA2 ;extra for custom routine
- JP EXTRA3 ;extra for custom routine
+ JP SENDR ; send character (via pop psw)
+ JP CAROK ; test for carrier
+ JP MDIN ; receive data byte
+ JP GETCHR ; get character from modem
+ JP RCVRDY ; check receive ready
+ JP SNDRDY ; check send ready
+ JP SPEED ; get speed value for file transfer time
+ JP EXTRA1 ; extra for custom routine
+ JP EXTRA2 ; extra for custom routine
+ JP EXTRA3 ; extra for custom routine
;
;-----------------------------------------------------------------------
;
@@ -63,7 +58,6 @@ CONOUT EQU 0 ; not used
; entries as appropriate.
;
MINIT:
-;
; Announce
LD DE,RBC ; RetroBrew Computers
LD C,9 ; BDOS string display function
@@ -78,13 +72,35 @@ MINIT:
JR Z,UINIT ; Do UBIOS setup
;
; Neither UNA nor RomWBW
- LD DE,BIOERR ; BIOS error message
+ LD DE,ERR_BIO ; BIOS error message
LD C,9 ; BDOS string display function
CALL BDOS ; Do it
JP 0 ; Bail out!
;
-HINIT:
+MINIT_RET:
+ PUSH HL ; Save HL (JP table adr)
+
+ ; Display port notification string
+ LD C,9 ; BDOS string display function
+ CALL BDOS ; Do it
+;
+ ; Newline
+ LD C,9 ; BDOS string display function
+ LD DE,CRLF ; Newline
+ CALL BDOS ; Do it
;
+ ; Copy real vectors into active jump table
+ POP HL ; Recover HL
+ LD DE,JPTBL ; Real jump table is destination
+ LD BC,7 * 3 ; Copy 7 3-byte entries
+ LDIR ; Do the copy
+;
+ ; Return with CPU speed in A
+ LD A,(CPUSPD) ; A := CPU speed in MHz
+ LD HL,(RCVSCL) ; HL := receive scalar
+ RET ; and return
+;
+HINIT:
; Display RomWBW notification string
LD DE,HBTAG ; BIOS notification string
LD C,9 ; BDOS string display function
@@ -103,10 +119,34 @@ HINIT:
RST 08 ; Do it, L := CPU speed in MHz
LD A,L ; Move it to A
LD (CPUSPD),A ; Save it
- JR MINIT1 ; Continue general initialization
;
-UINIT:
+ ; Get HBIOS character 0 device type
+ LD B,006H ; HBIOS DEVICE function 0x06
+ LD C,000H ; HBIOS char 0 device
+ RST 08 ; Do it, D=device type
+ LD A,D ; Put result in A
+ CP 000H ; UART?
+ JP Z,U_INIT ; If so, do UART init
+ CP 010H ; ASCI?
+ JP HINIT1 ; If so, handle it below
+ CP 080H ; USB-FIFO?
+ JP UF_INIT ; If so, do USB-FIFO init
+ JR HWERR ; Unknown hardware error
+;
+HINIT1:
+ ; Use platform to select ASCI driver
+ LD A,(PLTID) ; Get platform id
+ CP 4 ; N8?
+ JP Z,A4_INIT ; Init ASCI @ $40
+ CP 5 ; Mark IV?
+ JP Z,A4_INIT ; Init ASCI @ $40
+ CP 8 ; RCZ180?
+ JP Z,AC_INIT ; Init ASCI @ $C0
+ CP 10 ; SC126?
+ JP Z,AC_INIT ; Init ASCI @ $C0
+ JR HWERR ; Unknown hardware error
;
+UINIT:
; Display UNA notification string
LD DE,UBTAG ; BIOS notification string
LD C,9 ; BDOS string display function
@@ -115,7 +155,7 @@ UINIT:
; Get CPU speed from UNA and save it
LD C,0F8H ; UNA BIOS Get PHI function
RST 08 ; Returns speed in Hz in DE:HL
- LD B,4 ; Divide MHz in DE:HL by 100000H
+ LD B,4 ; Divide MHz in DE:HL by 100000H
UINIT1:
SRL D ; ... to get approx CPU speed in
RR E ; ...MHz. Throw away HL, and
@@ -123,85 +163,22 @@ UINIT1:
INC E ; Fix up for value truncation
LD A,E ; Put in A
LD (CPUSPD),A ; Save it
- JR MINIT1 ; Continue general initialization
-;
-MINIT1:
- ; NOTE: PLTID is only set if RomWBW HBIOS is active. This is OK
- ; because RC2014 is only supported by RomWBW HBIOS at this point.
- LD A,(PLTID) ; Get the platform id
- CP 7 ; Check for RC2014
- JR Z,RCINIT ; Handle RC2014 special
- CP 8 ; Check for RC2014 w/ Z180
- JR Z,ARCINIT ; Handle RC2014 w/ Z180
- CP 9 ; Check for Easy Z80
- JR Z,RCINIT ; Treat same as RC2014 for now
- CP 10 ; Check for SC126 w/ Z180
- JR Z,ARCINIT ; Handle SC126 w/ Z180
-;
- ; Check for Z180 which implies ASCI serial port
+;
+ ; Check CPU, Z80=UART, A180=ASCI @ $40
LD DE,00202H ; D := 2, E := 2
MLT DE ; DE := D * E == 4
BIT 2,E ; Bit 2 wil be set if mlt happend
- JR Z,MINIT2 ; Not Z180 (ASCI), look for others
- LD HL,ASCI_JPTBL ; Point to Z180 (ASCI) jump table
- LD DE,ASCI ; ASCI port notification string
- JR MINIT3 ; Complete the initialization
-;
-MINIT2:
- ; Not a Z180, so assume RBC standard UART serial port
- LD HL,UART_JPTBL ; Assume Z80 (UART)
- LD DE,UART ; UART port notification string
- JR MINIT3 ; Complete the initialization
-;
-RCINIT:
- ;; RC2014, use SIO
- ;; Suppress interrupts
- ;LD A,01H ; WR1
- ;OUT (S_CTLP),A ; Select WR1
- ;XOR A ; No interrupts
- ;OUT (S_CTLP),A ; Do it
- ;; Setup JP table
- ;LD HL,SIO_JPTBL ; HBIOS jump table address
- ;LD DE,SIO ; HBIOS console notification string
- ;JR MINIT3 ; Complete the initialization
-
- ; RC2014, use HBIOS calls
- LD HL,1250 ; Smaller receive loop tiemout scalar
- LD (RCVSCL),HL ; ... to compensate for BIOS overhead
- LD HL,HBIOS_JPTBL ; HBIOS jump table address
- LD DE,COMX ; HBIOS console notification string
- JR MINIT3 ; Complete the initialization
-;
-ARCINIT:
- ; RC2014 running Z180
- LD HL,ARC_JPTBL ; ASCI RC2014 jump table address
- LD DE,ASCIRC ; ASCI RC2014 console notification string
- JR MINIT3 ; Complete the initialization
-;
-MINIT3:
- PUSH HL ; Save HL
-
- ; Display port notification string
- LD C,9 ; BDOS string display function
- CALL BDOS ; Do it
+ JP Z,U_INIT ; UART initialization
+ JP A4_INIT ; ASCI @ $40 initialization
;
- ; Newline
+HWERR:
+ ; Failed to identify target comm hardware
+ LD DE,ERR_HW ; Hardware error message
LD C,9 ; BDOS string display function
- LD DE,CRLF ; Newline
CALL BDOS ; Do it
+ JP 0 ; Bail out!
;
- ; Copy real vectors into active jump table
- POP HL ; Recover HL
- LD DE,JPTBL ; Real jump table is destination
- LD BC,7 * 3 ; Copy 7 3-byte entries
- LDIR ; Do the copy
-;
- ; Return with CPU speed in A
- LD A,(CPUSPD) ; A := CPU speed in MHz
- LD HL,(RCVSCL) ; HL := receive scalar
- RET ; and return
-;
-; Identify active BIOS. RomWBW HBIOS=1, UNA UBIOS=2, else 0
+; Identify active BIOS. RomWBW HBIOS=1, UNA UBIOS=2, else 0
;
IDBIO:
;
@@ -238,28 +215,6 @@ IDBIO2:
XOR A ; Setup return value of 0
RET ; and done
;
-;
-;
-BIOID DB 0 ; BIOS ID, 1=HBIOS, 2=UBIOS
-PLTID DB 0 ; Platform ID
-CPUSPD DB 10 ; CPU speed in MHz
-RCVSCL DW 2800 ; RECV loop timeout scalar
-;
-RBC DB "RBC, 11-Aug-2019$"
-;
-UART DB ", UART0$"
-ASCI DB ", ASCI0$"
-ASCIRC DB ", ASCI0 (RC2014)$"
-SIO DB ", SIO$"
-COMX DB ", COM0$"
-;
-UBTAG DB " [UNA]$"
-HBTAG DB " [WBW]$"
-;
-CRLF DB 13, 10, "$"
-;
-BIOERR DB 13, 10, 13, 10, "++ Unknown BIOS ++", 13, 10, "$"
-;
;-----------------------------------------------------------------------
;
; Uninitialize modem
@@ -267,15 +222,27 @@ BIOERR DB 13, 10, 13, 10, "++ Unknown BIOS ++", 13, 10, "$"
UNINIT:
LD A,(BIOID)
CP 1 ; Is HBIOS?
- RET NZ ; If not, just return
-
- ; Reset character device 0
+ JR Z,H_UNINIT ; Handle HBIOS
+ CP 2 ; Is UBIOS?
+ JR Z,U_UNINIT ; Handle UBIOS
+ RET ; Just return
+;
+H_UNINIT:
+ ; HBIOS: Reset character device 0
LD B,04H ; HBIOS CIOINIT function 0x04
LD C,0 ; Unit = 0
LD DE,-1 ; Reset w/ current settings
RST 08 ; Do it
RET ; not initialized, so no 'UN-INITIALIZE'
;
+U_UNINIT:
+ ; UBIOS: Reset character device 0
+ LD C,10H ; UNA INIT function 0x10
+ LD B,0 ; Unit = 0
+ LD DE,-1 ; Reset w/ current settings
+ RST 08 ; Do it
+ RET ; not initialized, so no 'UN-INITIALIZE'
+;
;-----------------------------------------------------------------------
;
; The following are all dummy routines that are unused because MINIT
@@ -293,13 +260,33 @@ EXTRA2:
EXTRA3:
RET
;
+BIOID DB 0 ; BIOS ID, 1=HBIOS, 2=UBIOS
+PLTID DB 0 ; Platform ID
+CPUSPD DB 10 ; CPU speed in MHz
+RCVSCL DW 2800 ; RECV loop timeout scalar
+;
+RBC DB "RBC, 17-Aug-2019$"
+;
+U_LBL DB ", UART$"
+A4_LBL DB ", ASCI @ 40H$"
+AC_LBL DB ", ASCI @ C0H$"
+S_LBL DB ", SIO$"
+H_LBL DB ", COM$"
+UF_LBL DB ", USB-FIFO$"
+;
+UBTAG DB " [UNA]$"
+HBTAG DB " [WBW]$"
+;
+CRLF DB 13, 10, "$"
+;
+ERR_BIO DB 13, 10, 13, 10, "++ Unknown BIOS ++", 13, 10, "$"
+ERR_HW DB 13, 10, 13, 10, "++ Unknown Hardware ++", 13, 10, "$"
+;
;=======================================================================
;=======================================================================
;
; Standard RBC Projects 8250-like UART port @ 68H
;
-; Will be used for all RBC Z80 systems.
-;
;=======================================================================
;=======================================================================
;
@@ -316,12 +303,13 @@ U_RCVR EQU 01H ; value when ready to receive
U_PARE EQU 04H ; bit for parity error
U_OVRE EQU 02H ; bit for overrun error
U_FRME EQU 08H ; bit for framing error
+U_ERRS EQU U_FRME | U_OVRE | U_PARE
;
; Following jump table is dynamically patched into real jump
; table at program startup. See MINIT above. Note that only a
; subset of the jump table is overlaid (SENDR to SPEED).
;
-UART_JPTBL:
+U_JPTBL:
JP U_SENDR ; send character (via pop psw)
JP U_CAROK ; test for carrier
JP U_MDIN ; receive data byte
@@ -332,6 +320,15 @@ UART_JPTBL:
;
;-----------------------------------------------------------------------
;
+; UART initialization
+;
+U_INIT:
+ LD HL,U_JPTBL
+ LD DE,U_LBL
+ JP MINIT_RET
+;
+;-----------------------------------------------------------------------
+;
; Send character on top of stack
;
U_SENDR:
@@ -370,7 +367,7 @@ U_RCVRDY:
; With error detection (slower)
PUSH BC ; save scratch register
PUSH AF ; save full status on stack
- AND U_FRME | U_OVRE | U_PARE ; isolate line err bits
+ AND U_ERRS ; isolate line err bits
LD B,A ; save err status in B
POP AF ; get full status back
AND U_RCVB ; isolate ready bit
@@ -410,19 +407,17 @@ U_SPEED:
;=======================================================================
;=======================================================================
;
-; Standard RBC Projects Z180 primary ASCI port
-;
-; Will be used for all RBC Z180 systems.
+; Standard RBC Projects Z180 primary ASCI port @ 40H
;
;=======================================================================
;=======================================================================
;
; ASCI port constants
;
-A_DATP EQU 48H ;Z180 TSR - ASCI receive data port
-A_DATO EQU 46H ;Z180 TDR - ASCI transmit data port
-A_CTLP EQU 44H ;Z180 STAT - ASCI status port
-A_CTL2 EQU 40H ;Z180 CNTLA - ASCI control port
+A4_DATP EQU 48H ;Z180 TSR - ASCI receive data port
+A4_DATO EQU 46H ;Z180 TDR - ASCI transmit data port
+A4_CTLP EQU 44H ;Z180 STAT - ASCI status port
+A4_CTL2 EQU 40H ;Z180 CNTLA - ASCI control port
;
A_SNDB EQU 02H ;Z180 STAT:TDRE - xmit data reg empty bit
A_SNDR EQU 02H ;Z180 STAT:TDRE - xmit data reg empty value
@@ -431,34 +426,47 @@ A_RCVR EQU 80H ;Z180 STAT:RDRF - rcv data reg full value
A_PARE EQU 20H ;Z180 STAT:PE - parity error bit
A_OVRE EQU 40H ;Z180 STAT:OVRN - overrun error bit
A_FRME EQU 10H ;Z180 STAT:FE - framing error bit
+A_ERRS EQU A_FRME | A_OVRE | A_PARE
;
; Following jump table is dynamically patched over initial jump
; table at program startup. See MINIT above. Note that only a
; subset of the jump table is overlaid (SENDR to SPEED).
;
-ASCI_JPTBL:
- JP A_SENDR ;send character (via pop psw)
- JP A_CAROK ;test for carrier
- JP A_MDIN ;receive data byte
- JP A_GETCHR ;get character from modem
- JP A_RCVRDY ;check receive ready
- JP A_SNDRDY ;check send ready
- JP A_SPEED ;get speed value for file transfer time
+A4_JPTBL:
+ JP A4_SENDR ; send character (via pop psw)
+ JP A4_CAROK ; test for carrier
+ JP A4_MDIN ; receive data byte
+ JP A4_GETCHR ; get character from modem
+ JP A4_RCVRDY ; check receive ready
+ JP A4_SNDRDY ; check send ready
+ JP A4_SPEED ; get speed value for file transfer time
+;
+;-----------------------------------------------------------------------
+;
+; ASCI initialization
+;
+A4_INIT:
+ XOR A ; Clear interrupt enable flags
+ OUT0 (A4_CTLP),A ; Do it
+;
+ LD HL,A4_JPTBL
+ LD DE,A4_LBL
+ JP MINIT_RET
;
;-----------------------------------------------------------------------
;
; Send character on top of stack
;
-A_SENDR:
+A4_SENDR:
POP AF ; get character to send from stack
- OUT0 (A_DATO),A ; send to port
+ OUT0 (A4_DATO),A ; send to port
RET
;
;-----------------------------------------------------------------------
;
; Test and report carrier status, Z set if carrier present
;
-A_CAROK:
+A4_CAROK:
XOR A ; not used, always indicate present
RET
;
@@ -466,9 +474,9 @@ A_CAROK:
;
; Get a character (assume character ready has already been tested)
;
-A_MDIN:
-A_GETCHR:
- IN0 A,(A_DATP) ; read character from port
+A4_MDIN:
+A4_GETCHR:
+ IN0 A,(A4_DATP) ; read character from port
RET
;
;-----------------------------------------------------------------------
@@ -477,24 +485,24 @@ A_GETCHR:
; Error code returned in A register
; *** Error code does not seem to be used ***
;
-A_RCVRDY:
- IN0 A,(A_CTLP) ; get modem status
+A4_RCVRDY:
+ IN0 A,(A4_CTLP) ; get modem status
PUSH BC ; save scratch register
PUSH AF ; save full status on stack
- AND A_FRME | A_OVRE | A_PARE ; isolate line err bits
+ AND A_ERRS ; isolate line err bits
LD B,A ; save err status in B
-
+
; Z180 ASCI ports will stall if there are errors.
; Error bits are NOT cleared by merely reading
- ; the status register. Below, bit 3 of ASCI
- ; control register is written with a zero to
+ ; the status register. Below, bit 3 of ASCI
+ ; control register is written with a zero to
; clear error(s) if needed.
- JP Z,A_RCVRDY2 ; if no errs, continue
- IN0 A,(A_CTL2) ; get current control register
+ JP Z,A4_RCVRDY2 ; if no errs, continue
+ IN0 A,(A4_CTL2) ; get current control register
AND 0F7H ; force err reset bit to zero
- OUT0 (A_CTL2),A ; write control register
+ OUT0 (A4_CTL2),A ; write control register
-A_RCVRDY2:
+A4_RCVRDY2:
POP AF ; get full status back
AND A_RCVB ; isolate ready bit
CP A_RCVR ; test it (set flags)
@@ -506,8 +514,8 @@ A_RCVRDY2:
;
; Test for ready to send a character, Z = ready
;
-A_SNDRDY:
- IN A,(A_CTLP) ; get status
+A4_SNDRDY:
+ IN A,(A4_CTLP) ; get status
AND A_SNDB ; isolate transmit ready bit
CP A_SNDR ; test for ready value
RET
@@ -516,7 +524,7 @@ A_SNDRDY:
;
; Report baud rate (index into SPTBL returned in register A)
;
-A_SPEED:
+A4_SPEED:
LD A,8 ; arbitrarily return 9600 baud
RET
;
@@ -532,38 +540,50 @@ A_SPEED:
;
; ASCI port constants for RC2014
;
-AR_DATP EQU 0C8H ;Z180 TSR - ASCI receive data port
-AR_DATO EQU 0C6H ;Z180 TDR - ASCI transmit data port
-AR_CTLP EQU 0C4H ;Z180 STAT - ASCI status port
-AR_CTL2 EQU 0C0H ;Z180 CNTLA - ASCI control port
+AC_DATP EQU 0C8H ; Z180 TSR - ASCI receive data port
+AC_DATO EQU 0C6H ; Z180 TDR - ASCI transmit data port
+AC_CTLP EQU 0C4H ; Z180 STAT - ASCI status port
+AC_CTL2 EQU 0C0H ; Z180 CNTLA - ASCI control port
;
; Following jump table is dynamically patched over initial jump
; table at program startup. See MINIT above. Note that only a
; subset of the jump table is overlaid (SENDR to SPEED).
;
-ARC_JPTBL:
- JP AR_SENDR ;send character (via pop psw)
- JP AR_CAROK ;test for carrier
- JP AR_MDIN ;receive data byte
- JP AR_GETCHR ;get character from modem
- JP AR_RCVRDY ;check receive ready
- JP AR_SNDRDY ;check send ready
- JP AR_SPEED ;get speed value for file transfer time
+AC_JPTBL:
+ JP AC_SENDR ; send character (via pop psw)
+ JP AC_CAROK ; test for carrier
+ JP AC_MDIN ; receive data byte
+ JP AC_GETCHR ; get character from modem
+ JP AC_RCVRDY ; check receive ready
+ JP AC_SNDRDY ; check send ready
+ JP AC_SPEED ; get speed value for file transfer time
+;
+;-----------------------------------------------------------------------
+;
+; ASCI initialization
+;
+AC_INIT:
+ XOR A ; Clear interrupt enable flags
+ OUT0 (AC_CTLP),A ; Do it
+;
+ LD HL,AC_JPTBL
+ LD DE,AC_LBL
+ JP MINIT_RET
;
;-----------------------------------------------------------------------
;
; Send character on top of stack
;
-AR_SENDR:
+AC_SENDR:
POP AF ; get character to send from stack
- OUT0 (AR_DATO),A ; send to port
+ OUT0 (AC_DATO),A ; send to port
RET
;
;-----------------------------------------------------------------------
;
; Test and report carrier status, Z set if carrier present
;
-AR_CAROK:
+AC_CAROK:
XOR A ; not used, always indicate present
RET
;
@@ -571,9 +591,9 @@ AR_CAROK:
;
; Get a character (assume character ready has already been tested)
;
-AR_MDIN:
-AR_GETCHR:
- IN0 A,(AR_DATP) ; read character from port
+AC_MDIN:
+AC_GETCHR:
+ IN0 A,(AC_DATP) ; read character from port
RET
;
;-----------------------------------------------------------------------
@@ -582,24 +602,24 @@ AR_GETCHR:
; Error code returned in A register
; *** Error code does not seem to be used ***
;
-AR_RCVRDY:
- IN0 A,(AR_CTLP) ; get modem status
+AC_RCVRDY:
+ IN0 A,(AC_CTLP) ; get modem status
PUSH BC ; save scratch register
PUSH AF ; save full status on stack
- AND A_FRME | A_OVRE | A_PARE ; isolate line err bits
+ AND A_ERRS ; isolate line err bits
LD B,A ; save err status in B
-
+
; Z8S180 Rev. N ASCI ports will stall if there are line errors.
; Error bits are NOT cleared by merely reading
- ; the status register. Below, bit 3 of ASCI
- ; control register is written with a zero to
+ ; the status register. Below, bit 3 of ASCI
+ ; control register is written with a zero to
; clear error(s) if needed.
- JP Z,A_RCVRDY2 ; if no errs, continue
- IN0 A,(AR_CTL2) ; get current control register
+ JP Z,AC_RCVRDY2 ; if no errs, continue
+ IN0 A,(AC_CTL2) ; get current control register
AND 0F7H ; force err reset bit to zero
- OUT0 (AR_CTL2),A ; write control register
+ OUT0 (AC_CTL2),A ; write control register
-AR_RCVRDY2:
+AC_RCVRDY2:
POP AF ; get full status back
AND A_RCVB ; isolate ready bit
CP A_RCVR ; test it (set flags)
@@ -611,8 +631,8 @@ AR_RCVRDY2:
;
; Test for ready to send a character, Z = ready
;
-AR_SNDRDY:
- IN A,(AR_CTLP) ; get status
+AC_SNDRDY:
+ IN A,(AC_CTLP) ; get status
AND A_SNDB ; isolate transmit ready bit
CP A_SNDR ; test for ready value
RET
@@ -621,7 +641,7 @@ AR_SNDRDY:
;
; Report baud rate (index into SPTBL returned in register A)
;
-AR_SPEED:
+AC_SPEED:
LD A,8 ; arbitrarily return 9600 baud
RET
;
@@ -633,6 +653,10 @@ AR_SPEED:
;=======================================================================
;=======================================================================
;
+; Currently assumes the port address and ordering conventions of the
+; official RC2014 SIO module. Will not work with others such as EZZ80
+; or ZP.
+;
; SIO port constants
;
S_BASE EQU 80H ; SIO base port
@@ -648,7 +672,7 @@ S_RCVR EQU 01H ; value when ready to receive
; table at program startup. See MINIT above. Note that only a
; subset of the jump table is overlaid (SENDR to SPEED).
;
-SIO_JPTBL:
+S_JPTBL:
JP S_SENDR ; send character (via pop psw)
JP S_CAROK ; test for carrier
JP S_MDIN ; receive data byte
@@ -659,6 +683,21 @@ SIO_JPTBL:
;
;-----------------------------------------------------------------------
;
+; SIO initialization
+;
+S_INIT:
+ ; Suppress interrupts
+ LD A,01H ; WR1
+ OUT (S_CTLP),A ; Select WR1
+ XOR A ; No interrupts
+ OUT (S_CTLP),A ; Do it
+;
+ LD HL,S_JPTBL
+ LD DE,S_LBL
+ JP MINIT_RET
+;
+;-----------------------------------------------------------------------
+;
; Send character on top of stack
;
S_SENDR:
@@ -733,20 +772,32 @@ S_SPEED:
; table at program startup. See MINIT above. Note that only a
; subset of the jump table is overlaid (SENDR to SPEED).
;
-HBIOS_JPTBL:
- JP HB_SENDR ;send character (via pop psw)
- JP HB_CAROK ;test for carrier
- JP HB_MDIN ;receive data byte
- JP HB_GETCHR ;get character from modem
- JP HB_RCVRDY ;check receive ready
- JP HB_SNDRDY ;check send ready
- JP HB_SPEED ;get speed value for file transfer time
+H_JPTBL:
+ JP H_SENDR ; send character (via pop psw)
+ JP H_CAROK ; test for carrier
+ JP H_MDIN ; receive data byte
+ JP H_GETCHR ; get character from modem
+ JP H_RCVRDY ; check receive ready
+ JP H_SNDRDY ; check send ready
+ JP H_SPEED ; get speed value for file transfer time
+;
+;-----------------------------------------------------------------------
+;
+; HBIOS initialization
+;
+H_INIT:
+ LD HL,1250 ; Smaller receive loop timeout scalar
+ LD (RCVSCL),HL ; ... to compensate for BIOS overhead
+;
+ LD HL,H_JPTBL
+ LD DE,H_LBL
+ JP MINIT_RET
;
;-----------------------------------------------------------------------
;
; Send character on top of stack
;
-HB_SENDR:
+H_SENDR:
POP AF ; get character to send from stack
PUSH BC
PUSH DE
@@ -764,7 +815,7 @@ HB_SENDR:
;
; Test and report carrier status, Z set if carrier present
;
-HB_CAROK:
+H_CAROK:
XOR A ; not used, always indicate present
RET
;
@@ -774,23 +825,23 @@ HB_CAROK:
;
; This routine must NOT block.
;
-HB_MDIN:
-HB_GETCHR:
+H_MDIN:
+H_GETCHR:
PUSH BC
PUSH DE
PUSH HL
LD B,02H ; HBIOS IST function
LD C,0 ; console is unit 0 by fiat
RST 08 ; HBIOS call, A := bytes pending
- JR NZ,HB_MDIN1 ; If char(s) waiting, go get it
+ JR NZ,H_MDIN1 ; If char(s) waiting, go get it
XOR A ; otherwise, return null
- JR HB_MDIN2 ; and done
-HB_MDIN1:
+ JR H_MDIN2 ; and done
+H_MDIN1:
LD B,00H ; HBIOS IN function
LD C,0 ; console is unit 0 by fiat
RST 08 ; HBIOS call
LD A,E ; byte received to A
-HB_MDIN2:
+H_MDIN2:
POP HL
POP DE
POP BC
@@ -802,7 +853,7 @@ HB_MDIN2:
; Error code returned in A register
; *** Error code does not seem to be used ***
;
-HB_RCVRDY:
+H_RCVRDY:
PUSH BC
PUSH DE
PUSH HL
@@ -822,7 +873,7 @@ HB_RCVRDY:
;
; Test for ready to send a character, Z = ready
;
-HB_SNDRDY:
+H_SNDRDY:
PUSH BC
PUSH DE
PUSH HL
@@ -841,8 +892,104 @@ HB_SNDRDY:
;
; Report baud rate (index into SPTBL returned in register A)
;
-HB_SPEED:
+H_SPEED:
LD A,8 ; arbitrarily return 9600 baud
RET
+;
+;
+;=======================================================================
+;=======================================================================
+;
+; WILL SOWERBUTTS ECB USB-FIFO
+;
+;=======================================================================
+;=======================================================================
+;
+UF_BASE EQU 0CH
+UF_DATA EQU (UF_BASE+0)
+UF_STATUS EQU (UF_BASE+1)
+UF_SEND_IMM EQU (UF_BASE+2)
+;
+; Following jump table is dynamically patched over initial jump
+; table at program startup. See MINIT above. Note that only a
+; subset of the jump table is overlaid (SENDR to SPEED).
+;
+UF_JPTBL:
+ JP UF_SENDR ; send character (via pop psw)
+ JP UF_CAROK ; test for carrier
+ JP UF_MDIN ; receive data byte
+ JP UF_GETCHR ; get character from modem
+ JP UF_RCVRDY ; check receive ready
+ JP UF_SNDRDY ; check send ready
+ JP UF_SPEED ; get speed value for file transfer time
+;
+;-----------------------------------------------------------------------
+;
+; USB-FIFO initialization
+;
+UF_INIT:
+ LD HL,UF_JPTBL
+ LD DE,UF_LBL
+ JP MINIT_RET
+;
+;-----------------------------------------------------------------------
+;
+; Send character on top of stack
+;
+UF_SENDR:
+
+ POP AF ; get character to send from stack
+ OUT (UF_DATA),A ; WRITE TO FIFO
+ OUT (UF_SEND_IMM),A ; SEND IMMEDIATE
+ RET
+;
+;-----------------------------------------------------------------------
+;
+; Test and report carrier status, Z set if carrier present
+;
+UF_CAROK:
+ XOR A ; not used, always indicate present
+ RET
+;
+;-----------------------------------------------------------------------
+;
+; Get a character (assume character ready has already been tested)
+;
+; This routine must NOT block.
+;
+UF_MDIN:
+UF_GETCHR:
+ IN A,(UF_DATA) ; GET CHAR
+ RET
+;
+;-----------------------------------------------------------------------
+;
+; Test for character ready to receive, Z = ready
+; Error code returned in A register
+; *** Error code does not seem to be used ***
+;
+UF_RCVRDY:
+ IN A,(UF_STATUS) ; B7=0 IF CHAR AVAIL, =1 IF NO CHAR.
+ RLCA ; B0=0 IF CHAR AVAIL, =1 IF NO CHAR.
+ AND 00000001B ; A=0, ZF=1 IF NO CHAR, A=1, ZF=0 IF CHAR AVAIL,
+ LD A,0
+ RET
+;
+;-----------------------------------------------------------------------
+;
+; Test for ready to send a character, Z = ready
+;
+UF_SNDRDY:
+ IN A,(UF_STATUS) ; Bit 0=0 IF SPACE AVAIL, =1 IF FULL
+ AND 00000001B ; A=0, ZF=1 IF SPACE AVAIL, A=1, ZF=0 IF FULL.
+ RET
+;
+;-----------------------------------------------------------------------
+;
+; Report baud rate (index into SPTBL returned in register A)
+;
+UF_SPEED:
+ LD A,8 ; arbitrarily return 9600 baud
+ RET
;
END
diff --git a/Source/HBIOS/asci.asm b/Source/HBIOS/asci.asm
index 13ea9528..788a705a 100644
--- a/Source/HBIOS/asci.asm
+++ b/Source/HBIOS/asci.asm
@@ -5,10 +5,10 @@
;
; SETUP PARAMETER WORD:
; +-------+---+-------------------+ +---+---+-----------+---+-------+
-; | |RTS| ENCODED BAUD RATE | |DTR|XON| PARITY |STP| 8/7/6 |
+; | |RTS| ENCODED BAUD RATE | |DTR|XON| PARITY |STP| 8/7/6 |
; +-------+---+---+---------------+ ----+---+-----------+---+-------+
-; F E D C B A 9 8 7 6 5 4 3 2 1 0
-; -- MSB (D REGISTER) -- -- LSB (E REGISTER) --
+; F E D C B A 9 8 7 6 5 4 3 2 1 0
+; -- MSB (D REGISTER) -- -- LSB (E REGISTER) --
;
; STAT:
; 7 6 5 4 3 2 1 0
@@ -18,7 +18,7 @@
; | | | | | | | +-- TIE: TRANSMIT INTERRUPT ENABLE
; | | | | | | +---- TDRE: TRANSMIT DATA REGISTER EMPTY
; | | | | | +------ DCD0/CTS1E: CH0 CARRIER DETECT, CH1 CTS ENABLE
-; | | | | +-------- RIE: RECEIVE INTERRUPT ENABLE
+; | | | | +-------- RIE: RECEIVE INTERRUPT ENABLE
; | | | +---------- FE: FRAMING ERROR
; | | +------------ PE: PARITY ERROR
; | +-------------- OVRN: OVERRUN ERROR
@@ -33,7 +33,7 @@
; | | | | | | +---- MOD1: PARITY: 0=NONE, 1=ENABLED
; | | | | | +------ MOD2: DATA BITS: 0=7 BITS, 1=8 BITS
; | | | | +-------- MPBR/EFR: MULTIPROCESSOR BIT RECEIVE / ERROR FLAG RESET
-; | | | +---------- RTS0/CKA1D: CH0 RTS, CH1 CLOCK DISABLE
+; | | | +---------- RTS0/CKA1D: CH0 ~RTS, CH1 CLOCK DISABLE
; | | +------------ TE: TRANSMITTER ENABLE
; | +-------------- RE: RECEIVER ENABLE
; +---------------- MPE: MULTI-PROCESSOR MODE ENABLE
@@ -64,356 +64,536 @@
; | +-------------- DCD0 DISABLE
; +---------------- RDRF INT INHIBIT
;
+ASCI_BUFSZ .EQU 32 ; RECEIVE RING BUFFER SIZE
+;
+ASCI_NONE .EQU 0 ; NOT PRESENT
+ASCI_ASCI .EQU 1 ; ORIGINAL ASCI (Z8S180 REV. K)
+ASCI_ASCIB .EQU 2 ; REVISED ASCI W/ BRG & FIFO (Z8S180 REV. N)
+;
+ASCI0_BASE .EQU Z180_BASE ; RELATIVE TO Z180 INTERNAL IO PORTS
+ASCI1_BASE .EQU Z180_BASE + 1 ; RELATIVE TO Z180 INTERNAL IO PORTS
+;
+ASCI_RTS .EQU %00010000 ; ~RTS BIT OF CNTLA REG
+;
+#IF (INTMODE == 2)
+;
+ASCI0_IVT .EQU IVT(INT_SER0)
+ASCI1_IVT .EQU IVT(INT_SER1)
+;
+#ENDIF
+;
+;
+;
ASCI_PREINIT:
;
; SETUP THE DISPATCH TABLE ENTRIES
+; NOTE: INTS WILL BE DISABLED WHEN PREINIT IS CALLED AND THEY MUST REMIAIN
+; DISABLED.
+;
+ LD B,ASCI_CFGCNT ; LOOP CONTROL
+ XOR A ; ZERO TO ACCUM
+ LD (ASCI_DEV),A ; CURRENT DEVICE NUMBER
+ LD IY,ASCI_CFG ; POINT TO START OF CFG TABLE
+ASCI_PREINIT0:
+ PUSH BC ; SAVE LOOP CONTROL
+ CALL ASCI_INITUNIT ; HAND OFF TO GENERIC INIT CODE
+ POP BC ; RESTORE LOOP CONTROL
+;
+ LD A,(IY+1) ; GET THE ASCI TYPE DETECTED
+ OR A ; SET FLAGS
+ JR Z,ASCI_PREINIT2 ; SKIP IT IF NOTHING FOUND
+;
+ PUSH BC ; SAVE LOOP CONTROL
+ PUSH IY ; CFG ENTRY ADDRESS
+ POP DE ; ... TO DE
+ LD BC,ASCI_FNTBL ; BC := FUNCTION TABLE ADDRESS
+ CALL NZ,CIO_ADDENT ; ADD ENTRY IF ASCI FOUND, BC:DE
+ POP BC ; RESTORE LOOP CONTROL
+;
+ASCI_PREINIT2:
+ LD DE,ASCI_CFGSIZ ; SIZE OF CFG ENTRY
+ ADD IY,DE ; BUMP IY TO NEXT ENTRY
+ DJNZ ASCI_PREINIT0 ; LOOP UNTIL DONE
+;
+#IF (INTMODE >= 1)
+ ; SETUP INT VECTORS AS APPROPRIATE
+ LD A,(ASCI_DEV) ; GET DEVICE COUNT
+ OR A ; SET FLAGS
+ JR Z,ASCI_PREINIT3 ; IF ZERO, NO ASCI DEVICES, ABORT
+;
+#IF (INTMODE == 1)
+ ; ADD IM1 INT CALL LIST ENTRY
+ LD HL,ASCI_INT ; GET INT VECTOR
+ CALL HB_ADDIM1 ; ADD TO IM1 CALL LIST
+#ENDIF
;
-; LD B,2 ; ALWAYS 2 ASCI UNITS ON Z180
-; LD C,0 ; PHYSICAL UNIT INDEX
-;ASCI_PREINIT1:
-; PUSH BC ; SAVE LOOP CONTROL
-; LD D,C ; PHYSICAL UNIT
-; LD E,CIODEV_ASCI ; DEVICE TYPE
-; LD BC,ASCI_FNTBL ; BC := FUNCTION TABLE ADDRESS
-; CALL CIO_ADDENT ; ADD ENTRY, BC IS NOT DESTROYED
-; POP BC ; RESTORE LOOP CONTROL
-; INC C ; NEXT PHYSICAL UNIT
-; DJNZ ASCI_PREINIT1 ; LOOP UNTIL DONE
-;
- ; ASCI0 CHANNEL
- LD D,0 ; DEVICE ID
- LD E,CIODEV_ASCI ; DEVICE TYPE
- LD BC,ASCI0_FNTBL ; ASCI0 FUNCTION TABLE PTR
- CALL CIO_ADDENT
- LD DE,-1 ; DE := -1 TO INIT DEFAULT CONFIG
- CALL ASCI0_INITDEV ; INIT DEVICE
-;
- ; ASCI1 CHANNEL
- LD D,1 ; DEVICE ID
- LD E,CIODEV_ASCI ; DEVICE TYPE
- LD BC,ASCI1_FNTBL ; ASCI1 FUNCTION TABLE PTR
- CALL CIO_ADDENT
- LD DE,-1 ; DE := -1 TO INIT DEFAULT CONFIG
- CALL ASCI1_INITDEV ; INIT DEVICE
+#IF (INTMODE == 2)
+ ; SETUP IM2 VECTORS
+ LD HL,ASCI_INT0
+ LD (ASCI0_IVT),HL ; IVT INDEX
+ LD HL,ASCI_INT1
+ LD (ASCI1_IVT),HL ; IVT INDEX
+#ENDIF
+;
+#ENDIF
;
+ASCI_PREINIT3:
XOR A ; SIGNAL SUCCESS
- RET
+ RET ; AND RETURN
;
+; ASCI INITIALIZATION ROUTINE
;
+ASCI_INITUNIT:
+ CALL ASCI_DETECT ; DETERMINE ASCI TYPE
+ LD (IY+1),A ; SAVE IN CONFIG TABLE
+ OR A ; SET FLAGS
+ RET Z ; ABORT IF NOTHING THERE
+
+ ; UPDATE WORKING ASCI DEVICE NUM
+ LD HL,ASCI_DEV ; POINT TO CURRENT UART DEVICE NUM
+ LD A,(HL) ; PUT IN ACCUM
+ INC (HL) ; INCREMENT IT (FOR NEXT LOOP)
+ LD (IY),A ; UPDATE UNIT NUM
;
-ASCI_INIT:
+ ; IT IS EASY TO SPECIFY A SERIAL CONFIG THAT CANNOT BE IMPLEMENTED
+ ; DUE TO THE CONSTRAINTS OF THE ASCI. HERE WE FORCE A GENERIC
+ ; FAILSAFE CONFIG ONTO THE CHANNEL. IF THE SUBSEQUENT "REAL"
+ ; CONFIG FAILS, AT LEAST THE CHIP WILL BE ABLE TO SPIT DATA OUT
+ ; AT A RATIONAL BAUD/DATA/PARITY/STOP CONFIG.
+ CALL ASCI_INITSAFE
;
- ; ASCI0
- CALL NEWLINE ; FORMATTING
- PRTS("ASCI0: IO=0x$") ; PREFIX
- LD A,Z180_TDR0 ; LOAD TDR PORT ADDRESS
- CALL PRTHEXBYTE ; PRINT IT
-
- CALL PC_COMMA ; FORMATTING
- LD A,Z180_RDR0 ; LOAD RDR PORT ADDRESS
- CALL PRTHEXBYTE ; PRINT IT
-
- PRTS(" MODE=$") ; FORMATTING
- LD DE,(ASCI0_CONFIG) ; LOAD CONFIG
- CALL PS_PRTSC0 ; PRINT IT
+ ; SET DEFAULT CONFIG
+ LD DE,-1 ; LEAVE CONFIG ALONE
+ ; CALL INITDEV TO IMPLEMENT CONFIG, BUT NOTE THAT WE CALL
+ ; THE INITDEVX ENTRY POINT THAT DOES NOT ENABLE/DISABLE INTS!
+ JP ASCI_INITDEVX ; IMPLEMENT IT AND RETURN
;
- ; ASCI1
- CALL NEWLINE ; FORMATTING
- PRTS("ASCI1: IO=0x$") ; PREFIX
- LD A,Z180_TDR1 ; LOAD TDR PORT ADDRESS
- CALL PRTHEXBYTE ; PRINT IT
-
- CALL PC_COMMA ; FORMATTING
- LD A,Z180_RDR1 ; LOAD RDR PORT ADDRESS
- CALL PRTHEXBYTE ; PRINT IT
-
- PRTS(" MODE=$") ; FORMATTING
- LD DE,(ASCI1_CONFIG) ; LOAD CONFIG
- CALL PS_PRTSC0 ; PRINT IT
;
- XOR A
- RET
;
-; DRIVER ASCI0 FUNCTION TABLE
-;
-ASCI0_FNTBL:
- .DW ASCI0_IN
- .DW ASCI0_OUT
- .DW ASCI0_IST
- .DW ASCI0_OST
- .DW ASCI0_INITDEV
- .DW ASCI0_QUERY
- .DW ASCI0_DEVICE
-#IF (($ - ASCI0_FNTBL) != (CIO_FNCNT * 2))
- .ECHO "*** INVALID ASCI0 FUNCTION TABLE ***\n"
-#ENDIF
+ASCI_INIT:
+ LD B,ASCI_CFGCNT ; COUNT OF POSSIBLE ASCI UNITS
+ LD IY,ASCI_CFG ; POINT TO START OF CFG TABLE
+ASCI_INIT1:
+ PUSH BC ; SAVE LOOP CONTROL
+ LD A,(IY+1) ; GET ASCI TYPE
+ OR A ; SET FLAGS
+ CALL NZ,ASCI_PRTCFG ; PRINT IF NOT ZERO
+ POP BC ; RESTORE LOOP CONTROL
+ LD DE,ASCI_CFGSIZ ; SIZE OF CFG ENTRY
+ ADD IY,DE ; BUMP IY TO NEXT ENTRY
+ DJNZ ASCI_INIT1 ; LOOP TILL DONE
;
-ASCI0_IN:
- CALL ASCI0_IST
- OR A
- JR Z,ASCI0_IN
- IN0 A,(Z180_RDR0) ; READ THE CHAR
- LD E,A
- RET
+ XOR A ; SIGNAL SUCCESS
+ RET ; DONE
;
-ASCI0_IST:
- ; CHECK FOR ERROR FLAGS
- IN0 A,(Z180_STAT0)
- AND 70H ; PARITY, FRAMING, OR OVERRUN ERROR
- JR Z,ASCI0_IST1 ; ALL IS WELL, CHECK FOR DATA
+; RECEIVE INTERRUPT HANDLER
;
- ; CLEAR ERROR(S) OR NOTHING FURTHER CAN BE RECEIVED!!!
- IN0 A,(Z180_CNTLA0)
- RES 3,A ; CLEAR EFR (ERROR FLAG RESET)
- OUT0 (Z180_CNTLA0),A
+#IF (INTMODE > 0)
;
-ASCI0_IST1:
- ; CHECK FOR STAT0.RDRF (DATA READY)
- IN0 A,(Z180_STAT0) ; READ LINE STATUS REGISTER
- AND $80 ; TEST IF DATA IN RECEIVE BUFFER
- JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN
- XOR A
- INC A ; SIGNAL CHAR READY, A = 1
- RET
+; IM1 ENTRY POINT
;
-ASCI0_OUT:
- CALL ASCI0_OST
- OR A
- JR Z,ASCI0_OUT
- LD A,E
- OUT0 (Z180_TDR0),A
- RET
+ASCI_INT:
+ ; CHECK/HANDLE FIRST PORT
+ LD A,(ASCI0_CFG + 1) ; GET ASCI TYPE FOR FIRST ASCI
+ OR A ; SET FLAGS
+ CALL NZ,ASCI_INT0 ; CALL IF EXISTS
+ RET NZ ; DONE IF INT HANDLED
;
-ASCI0_OST:
- IN0 A,(Z180_STAT0)
- AND $02
- JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN
- XOR A
- INC A ; SIGNAL BUFFER EMPTY, A = 1
- RET
+ ; CHECK/HANDLE SECOND PORT
+ LD A,(ASCI1_CFG + 1) ; GET ASCI TYPE FOR SECOND ASCI
+ OR A ; SET FLAGS
+ CALL NZ,ASCI_INT1 ; CALL IF EXISTS
;
-ASCI0_INITDEV:
- ; TEST FOR -1 WHICH MEANS USE CURRENT CONFIG (JUST REINIT)
- LD A,D ; TEST DE FOR
- AND E ; ... VALUE OF -1
- INC A ; ... SO Z SET IF -1
- JR NZ,ASCI0_INITDEV1 ; IF NEW CONFIG (NOT -1), IMPLEMENT IT
- LD DE,(ASCI0_CONFIG) ; OTHERWISE, LOAD EXISTING CONFIG
+ RET ; DONE
;
-ASCI0_INITDEV1:
- ; DETERMINE APPROPRIATE CNTLB VALUE (BASED ON BAUDRATE & CPU SPEED)
- LD A,D ; BYTE W/ ENCODED BAUD RATE
- AND $1F ; ISOLATE BITS
- LD L,A ; MOVE TO L
- LD H,0 ; CLEAR MSB
- PUSH DE ; SAVE CONFIG
- CALL ASCI_CNTLB ; DERIVE CNTLB VALUE IN C
- POP DE ; RESTORE CONFIG
- ;CALL TSTPT
- RET NZ ; ABORT ON ERROR
+; IM2 ENTRY POINTS
+;
+ASCI_INT0:
+ ; INTERRUPT HANDLER FOR FIRST ASCI (ASCI0)
+ LD IY,ASCI0_CFG ; POINT TO ASCI0 CFG
+ JR ASCI_INTRCV
+;
+ASCI_INT1:
+ ; INTERRUPT HANDLER FOR SECOND ASCI (ASCI1)
+ LD IY,ASCI1_CFG ; POINT TO ASCI1 CFG
+ JR ASCI_INTRCV
+;
+; HANDLE INT FOR A SPECIFIC CHANNEL
+; BASED ON UNIT CFG POINTED TO BY IY
+;
+ASCI_INTRCV:
+ ; CHECK TO SEE IF SOMETHING IS ACTUALLY THERE
+ CALL ASCI_ICHK ; CHECK FOR CHAR PENDING
+ RET Z ; RETURN IF NOTHING AVAILABLE
+;
+ASCI_INTRCV1:
+ ; RECEIVE CHARACTER INTO BUFFER
+ LD A,(IY+3) ; BASE PORT TO A
+ ADD A,8 ; BUMP TO RDR PORT
+ LD C,A ; PUT IN C, B IS STILL ZERO
+ IN A,(C) ; READ PORT
+ LD B,A ; SAVE BYTE READ
+ LD L,(IY+6) ; SET HL TO
+ LD H,(IY+7) ; ... START OF BUFFER STRUCT
+ LD A,(HL) ; GET COUNT
+ CP ASCI_BUFSZ ; COMPARE TO BUFFER SIZE
+ JR Z,ASCI_INTRCV4 ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED
+ INC A ; INCREMENT THE COUNT
+ LD (HL),A ; AND SAVE IT
+ CP ASCI_BUFSZ / 2 ; BUFFER GETTING FULL?
+ JR NZ,ASCI_INTRCV2 ; IF NOT, BYPASS CLEARING RTS
+ ; CLEAR RTS
+ ; THE SECONDARY ASCI PORT ON Z180 ACTUALLY HAS NO RTS LINE
+ ; AND THE CNTLA BIT FOR THIS PORT CONTROLS THE FUNCTION OF THE
+ ; MULTIPLEXED CKA1/~TEND0 LINE. BELOW, WE TEST REG C TO SEE IF
+ ; IT IS AN ODD NUMBERED PORT. IF SO, WE MUST BE ON THE SECONDARY
+ ; SERIAL PORT, SO WE NEED TO BYPASS MANIPULATING THE RTS BIT.
+ BIT 0,C ; IS C ADDRESSING AN ODD NUMBERED PORT?
+ JR NZ,ASCI_INTRCV2 ; IF SO, THIS IS SEC SERIAL, NO RTS!
+ PUSH BC ; PRESERVE READ CHAR
+ LD C,(IY+3) ; CNTLA PORT ADR
+ LD B,0 ; MSB FOR 16 BIT I/O
+ IN A,(C) ; GET CUR CNTLA VAL
+ OR ASCI_RTS ; DEASSERT ~RTS
+ OUT (C),A ; DO IT
+ POP BC ; RESTORE READ CHAR
+ASCI_INTRCV2:
+ INC HL ; HL NOW HAS ADR OF HEAD PTR
+ PUSH HL ; SAVE ADR OF HEAD PTR
+ LD A,(HL) ; DEREFERENCE HL
+ INC HL
+ LD H,(HL)
+ LD L,A ; HL IS NOW ACTUAL HEAD PTR
+ LD (HL),B ; SAVE CHARACTER RECEIVED IN BUFFER AT HEAD
+ INC HL ; BUMP HEAD POINTER
+ POP DE ; RECOVER ADR OF HEAD PTR
+ LD A,L ; GET LOW BYTE OF HEAD PTR
+ SUB ASCI_BUFSZ+4 ; SUBTRACT SIZE OF BUFFER AND POINTER
+ CP E ; IF EQUAL TO START, HEAD PTR IS PAST BUF END
+ JR NZ,ASCI_INTRCV3 ; IF NOT, BYPASS
+ LD H,D ; SET HL TO
+ LD L,E ; ... HEAD PTR ADR
+ INC HL ; BUMP PAST HEAD PTR
+ INC HL
+ INC HL
+ INC HL ; ... SO HL NOW HAS ADR OF ACTUAL BUFFER START
+ASCI_INTRCV3:
+ EX DE,HL ; DE := HEAD PTR VAL, HL := ADR OF HEAD PTR
+ LD (HL),E ; SAVE UPDATED HEAD PTR
+ INC HL
+ LD (HL),D
+ ; CHECK FOR MORE PENDING...
+ CALL ASCI_ICHK ; CHECK FOR CHAR PENDING
+ JR NZ,ASCI_INTRCV1 ; IF SO, LOOP TO HANDLE
+ASCI_INTRCV4:
+ OR $FF ; NZ SET TO INDICATE INT HANDLED
+ RET ; AND RETURN
;
- LD B,$64 ; B := DEFAULT CNTLB VALUE
-
- ; DATA BITS
- LD A,E ; LOAD CONFIG BYTE
- AND $03 ; ISOLATE DATA BITS
- CP $03 ; 8 DATA BITS?
- JR Z,ASCI0_INITDEV2 ; IF SO, NO CHG, CONTINUE
- RES 2,B ; RESET CNTLA BIT 2 FOR 7 DATA BITS
-
-ASCI0_INITDEV2:
- ; STOP BITS
- BIT 2,E ; TEST STOP BITS CONFIG BIT
- JR Z,ASCI0_INITDEV3 ; IF CLEAR, NO CHG, CONTINUE
- SET 0,B ; SET CNTLA BIT 0 FOR 2 STOP BITS
-
-ASCI0_INITDEV3:
- ; PARITY ENABLE
- BIT 3,E ; TEST PARITY ENABLE CONFIG BIT
- JR Z,ASCI0_INITDEV4 ; NO PARITY, SKIP ALL PARITY CHGS
- SET 1,B ; SET CNTLA BIT 1 FOR PARITY ENABLE
-
- ; PARITY EVEN/ODD
- BIT 4,E ; TEST EVEN PARITY CONFIG BIT
- JR NZ,ASCI0_INITDEV4 ; EVEN PARITY, NO CHG, CONTINUE
- SET 4,C ; SET CNTLB BIT 4 FOR ODD PARITY
-
-ASCI0_INITDEV4:
- ; IMPLEMENT CONFIGURATION
- LD A,$66 ; LOAD DEFAULT ASEXT VALUE
- OUT0 (Z180_ASEXT0),A ; SET IT
- LD A,B ; FINAL CNTLA VALUE TO ACCUM
- OUT0 (Z180_CNTLA0),A ; WRITE TO CNTLA REGISTER
- LD A,C ; FINAL CNTLB VALUE TO ACCUM
- OUT0 (Z180_CNTLB0),A ; WRITE TO CNTLA REGISTER
-;
- LD (ASCI0_CONFIG),DE ; RECORD UPDATED CONFIG
+#ENDIF
+;
+; DRIVER FUNCTION TABLE
+;
+ASCI_FNTBL:
+ .DW ASCI_IN
+ .DW ASCI_OUT
+ .DW ASCI_IST
+ .DW ASCI_OST
+ .DW ASCI_INITDEV
+ .DW ASCI_QUERY
+ .DW ASCI_DEVICE
+#IF (($ - ASCI_FNTBL) != (CIO_FNCNT * 2))
+ .ECHO "*** INVALID ASCI FUNCTION TABLE ***\n"
+#ENDIF
+;
+#IF (INTMODE == 0)
+;
+ASCI_IN:
+ CALL ASCI_IST ; CHECK FOR CHAR READY
+ JR Z,ASCI_IN ; IF NOT, LOOP
+ LD A,(IY+3) ; BASE REG
+ ADD A,8 ; Z180 RDR REG OFFSET
+ LD C,A ; PUT IN C FOR I/O
+ LD B,0 ; MSB FOR 16 BIT I/O
+ IN E,(C) ; GET CHAR
XOR A ; SIGNAL SUCCESS
RET ; DONE
;
-ASCI0_QUERY:
- LD DE,(ASCI0_CONFIG)
- XOR A
- RET
+#ELSE
+;
+ASCI_IN:
+ CALL ASCI_IST ; SEE IF CHAR AVAILABLE
+ JR Z,ASCI_IN ; LOOP UNTIL SO
+ HB_DI ; AVOID COLLISION WITH INT HANDLER
+ LD L,(IY+6) ; SET HL TO
+ LD H,(IY+7) ; ... START OF BUFFER STRUCT
+ LD A,(HL) ; GET COUNT
+ DEC A ; DECREMENT COUNT
+ LD (HL),A ; SAVE UPDATED COUNT
+ CP ASCI_BUFSZ / 4 ; BUFFER LOW THRESHOLD
+ JR NZ,ASCI_IN1 ; IF NOT, BYPASS SETTING RTS
+ ; SET RTS
+ ; THE SECONDARY ASCI PORT ON Z180 ACTUALLY HAS NO RTS LINE
+ ; AND THE CNTLA BIT FOR THIS PORT CONTROLS THE FUNCTION OF THE
+ ; MULTIPLEXED CKA1/~TEND0 LINE. BELOW, WE TEST REG C TO SEE IF
+ ; IT IS AN ODD NUMBERED PORT. IF SO, WE MUST BE ON THE SECONDARY
+ ; SERIAL PORT, SO WE NEED TO BYPASS MANIPULATING THE RTS BIT.
+ LD C,(IY+3) ; CNTLA PORT ADR
+ BIT 0,C ; IS C ADDRESSING AN ODD NUMBERED PORT?
+ JR NZ,ASCI_IN1 ; IF SO, THIS IS SEC SERIAL, NO RTS!
+ LD B,0 ; MSB FOR 16 BIT I/O
+ IN A,(C) ; GET CUR CNTLA VAL
+ AND ~ASCI_RTS ; ASSERT ~RTS
+ OUT (C),A ; DO IT
+ASCI_IN1:
+ INC HL ; HL := ADR OF TAIL PTR
+ INC HL ; "
+ INC HL ; "
+ PUSH HL ; SAVE ADR OF TAIL PTR
+ LD A,(HL) ; DEREFERENCE HL
+ INC HL
+ LD H,(HL)
+ LD L,A ; HL IS NOW ACTUAL TAIL PTR
+ LD C,(HL) ; C := CHAR TO BE RETURNED
+ INC HL ; BUMP TAIL PTR
+ POP DE ; RECOVER ADR OF TAIL PTR
+ LD A,L ; GET LOW BYTE OF TAIL PTR
+ SUB ASCI_BUFSZ+2 ; SUBTRACT SIZE OF BUFFER AND POINTER
+ CP E ; IF EQUAL TO START, TAIL PTR IS PAST BUF END
+ JR NZ,ASCI_IN2 ; IF NOT, BYPASS
+ LD H,D ; SET HL TO
+ LD L,E ; ... TAIL PTR ADR
+ INC HL ; BUMP PAST TAIL PTR
+ INC HL ; ... SO HL NOW HAS ADR OF ACTUAL BUFFER START
+ASCI_IN2:
+ EX DE,HL ; DE := TAIL PTR VAL, HL := ADR OF TAIL PTR
+ LD (HL),E ; SAVE UPDATED TAIL PTR
+ INC HL ; "
+ LD (HL),D ; "
+ LD E,C ; MOVE CHAR TO RETURN TO E
+ HB_EI ; INTERRUPTS OK AGAIN
+ XOR A ; SIGNAL SUCCESS
+ RET ; AND DONE
;
-ASCI0_DEVICE:
- LD D,CIODEV_ASCI ; D := DEVICE TYPE
- LD E,0 ; E := PHYSICAL UNIT
- LD C,$00 ; C := DEVICE TYPE, 0x00 IS RS-232
+#ENDIF
+;
+;
+;
+ASCI_OUT:
+ CALL ASCI_OST ; CHECK IF OUTPUT REGISTER READY
+ JR Z,ASCI_OUT ; LOOP UNTIL SO
+ LD A,(IY+3) ; GET ASCI BASE REG
+ ADD A,6 ; Z180 TDR REG OFFSET
+ LD C,A ; PUT IN C FOR I/O
+ LD B,0 ; MSB FOR 16 BIT I/O
+ OUT (C),E ; WRITE CHAR
XOR A ; SIGNAL SUCCESS
- RET
+ RET ; DONE
+;
+;
+;
+#IF (INTMODE == 0)
+;
+ASCI_IST:
+ CALL ASCI_ICHK ; ASCI INPUT CHECK
+ JP Z,CIO_IDLE ; IF NOT READY, RETURN VIA IDLE PROCESSING
+ RET ; NORMAL RETURN
+;
+#ELSE
+;
+ASCI_IST:
+ LD L,(IY+6) ; GET ADDRESS
+ LD H,(IY+7) ; ... OF RECEIVE BUFFER
+ LD A,(HL) ; BUFFER UTILIZATION COUNT
+ OR A ; SET FLAGS
+ JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING
+ RET ; DONE
;
-; DRIVER ASCI1 FUNCTION TABLE
-;
-ASCI1_FNTBL:
- .DW ASCI1_IN
- .DW ASCI1_OUT
- .DW ASCI1_IST
- .DW ASCI1_OST
- .DW ASCI1_INITDEV
- .DW ASCI1_QUERY
- .DW ASCI1_DEVICE
-#IF (($ - ASCI1_FNTBL) != (CIO_FNCNT * 2))
- .ECHO "*** INVALID ASCI1 FUNCTION TABLE ***\n"
#ENDIF
-ASCI1:
- LD A,B ; GET REQUESTED FUNCTION
- AND $0F ; ISOLATE SUB-FUNCTION
- JR Z,ASCI1_IN
- DEC A
- JR Z,ASCI1_OUT
- DEC A
- JR Z,ASCI1_IST
- DEC A
- JR Z,ASCI1_OST
- DEC A
- JP Z,ASCI1_INITDEV
- DEC A
- JP Z,ASCI1_QUERY
- DEC A
- JP Z,ASCI1_DEVICE
- CALL PANIC
-;
-ASCI1_IN:
- CALL ASCI1_IST
- OR A
- JR Z,ASCI1_IN
- IN0 A,(Z180_RDR1) ; READ THE CHAR
- LD E,A
- RET
;
-ASCI1_IST:
- ; CHECK FOR ERROR FLAGS
- IN0 A,(Z180_STAT1)
- AND 70H ; PARITY, FRAMING, OR OVERRUN ERROR
- JR Z,ASCI1_IST1 ; ALL IS WELL, CHECK FOR DATA
;
- ; CLEAR ERROR(S) OR NOTHING FURTHER CAN BE RECEIVED!!!
- IN0 A,(Z180_CNTLA1)
- RES 3,A ; CLEAR EFR (ERROR FLAG RESET)
- OUT0 (Z180_CNTLA1),A
;
-ASCI1_IST1: ; CHECK FOR STAT0.RDRF (DATA READY)
- IN0 A,(Z180_STAT1) ; READ LINE STATUS REGISTER
- AND $80 ; TEST IF DATA IN RECEIVE BUFFER
- JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN
- XOR A
- INC A ; SIGNAL CHAR READY, A = 1
- RET
+ASCI_OST:
+ LD A,(IY+3) ; GET ASCI BASE REG
+ ADD A,4 ; Z180 STAT REG OFFSET
+ LD C,A ; PUT IN C FOR I/O
+ LD B,0 ; MSB FOR 16 BIT I/O
+ IN A,(C) ; READ STATUS
+ AND $02 ; CHECK BIT FOR OUTPUT READY
+ JP Z,CIO_IDLE ; IF NOT, DO IDLE PROCESSING AND RETURN
+ XOR A ; OTHERWISE SIGNAL
+ INC A ; ... BUFFER EMPTY, A = 1
+ RET ; DONE
;
-ASCI1_OUT:
- CALL ASCI1_OST
- OR A
- JR Z,ASCI1_OUT
- LD A,E
- OUT0 (Z180_TDR1),A
- RET
+; AT INITIALIZATION THE SETUP PARAMETER WORD IS TRANSLATED TO THE FORMAT
+; REQUIRED BY THE ASCI AND STORED IN A PORT/REGISTER INITIALIZATION TABLE,
+; WHICH IS THEN LOADED INTO THE ASCI.
;
-ASCI1_OST:
- IN0 A,(Z180_STAT1)
- AND $02
- JR Z,ASCI1_OST
- JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN
- XOR A
- INC A ; SIGNAL BUFFER EMPTY, A = 1
- RET
+; NOTE THAT THERE ARE TWO ENTRY POINTS. INITDEV WILL DISABLE/ENABLE INTS
+; AND INITDEVX WILL NOT. THIS IS DONE SO THAT THE PREINIT ROUTINE ABOVE
+; CAN AVOID ENABLING/DISABLING INTS.
+;
+ASCI_INITDEV:
+ HB_DI ; DISABLE INTS
+ CALL ASCI_INITDEVX ; DO THE WORK
+ HB_EI ; INTS BACK ON
+ RET ; DONE
+;
+ASCI_INITDEVX:
+;
+; THIS ENTRY POINT BYPASSES DISABLING/ENABLING INTS WHICH IS REQUIRED BY
+; PREINIT ABOVE. PREINIT IS NOT ALLOWED TO ENABLE INTS!
;
-ASCI1_INITDEV:
; TEST FOR -1 WHICH MEANS USE CURRENT CONFIG (JUST REINIT)
LD A,D ; TEST DE FOR
AND E ; ... VALUE OF -1
INC A ; ... SO Z SET IF -1
- JR NZ,ASCI1_INITDEV1 ; IF NEW CONFIG (NOT -1), IMPLEMENT IT
- LD DE,(ASCI1_CONFIG) ; OTHERWISE, LOAD EXISTING CONFIG
-;
-ASCI1_INITDEV1:
+ JR NZ,ASCI_INITDEV1 ; IF DE == -1, REINIT CURRENT CONFIG
+;
+ ; LOAD EXISTING CONFIG TO REINIT
+ LD E,(IY+4) ; LOW BYTE
+ LD D,(IY+5) ; HIGH BYTE
+;
+ASCI_INITDEV1:
+;
+ LD A,E ; GET CONFIG LSB
+ AND $E0 ; CHECK FOR DTR, XON, PARITY=MARK/SPACE
+ JR NZ,ASCI_INITFAIL ; IF ANY BIT SET, FAIL, NOT SUPPORTED
+;
; DETERMINE APPROPRIATE CNTLB VALUE (BASED ON BAUDRATE & CPU SPEED)
LD A,D ; BYTE W/ ENCODED BAUD RATE
AND $1F ; ISOLATE BITS
LD L,A ; MOVE TO L
LD H,0 ; CLEAR MSB
PUSH DE ; SAVE CONFIG
- CALL ASCI_CNTLB ; DERIVE CNTLB VALUE
+ CALL ASCI_CNTLB ; DERIVE CNTLB VALUE TO C
POP DE ; RESTORE CONFIG
- ;CALL TSTPT
- RET NZ ; ABORT ON ERROR
+ JR NZ,ASCI_INITFAIL ; ABORT ON ERROR
+;
+ ; BUILD CNTLA VALUE IN REGISTER B
+ LD B,$64 ; START WITH DEFAULT CNTLA VALUE
;
- LD B,$64 ; B := DEFAULT CNTLB VALUE
-
; DATA BITS
LD A,E ; LOAD CONFIG BYTE
AND $03 ; ISOLATE DATA BITS
CP $03 ; 8 DATA BITS?
- JR Z,ASCI1_INITDEV2 ; IF SO, NO CHG, CONTINUE
+ JR Z,ASCI_INITDEV2 ; IF SO, NO CHG, CONTINUE
RES 2,B ; RESET CNTLA BIT 2 FOR 7 DATA BITS
-
-ASCI1_INITDEV2:
+;
+ASCI_INITDEV2:
; STOP BITS
BIT 2,E ; TEST STOP BITS CONFIG BIT
- JR Z,ASCI1_INITDEV3 ; IF CLEAR, NO CHG, CONTINUE
+ JR Z,ASCI_INITDEV3 ; IF CLEAR, NO CHG, CONTINUE
SET 0,B ; SET CNTLA BIT 0 FOR 2 STOP BITS
-
-ASCI1_INITDEV3:
+;
+ASCI_INITDEV3:
; PARITY ENABLE
BIT 3,E ; TEST PARITY ENABLE CONFIG BIT
- JR Z,ASCI1_INITDEV4 ; NO PARITY, SKIP ALL PARITY CHGS
+ JR Z,ASCI_INITDEV4 ; NO PARITY, SKIP ALL PARITY CHGS
SET 1,B ; SET CNTLA BIT 1 FOR PARITY ENABLE
; PARITY EVEN/ODD
BIT 4,E ; TEST EVEN PARITY CONFIG BIT
- JR NZ,ASCI1_INITDEV4 ; EVEN PARITY, NO CHG, CONTINUE
+ JR NZ,ASCI_INITDEV4 ; EVEN PARITY, NO CHG, CONTINUE
SET 4,C ; SET CNTLB BIT 4 FOR ODD PARITY
-
-ASCI1_INITDEV4:
+;
+ASCI_INITDEV4:
+ ; SAVE CONFIG PERMANENTLY NOW
+ LD (IY+4),E ; SAVE LOW WORD
+ LD (IY+5),D ; SAVE HI WORD
+ JR ASCI_INITGO
+;
+ASCI_INITSAFE:
+ LD B,$64 ; CNTLA FAILSAFE VALUE
+ LD C,$20 ; CNTLB FAILSAFE VALUE
+;
+ASCI_INITGO:
; IMPLEMENT CONFIGURATION
- LD A,$66 ; LOAD DEFAULT ASEXT VALUE
- OUT0 (Z180_ASEXT1),A ; SET IT
- LD A,B ; FINAL CNTLA VALUE TO ACCUM
- OUT0 (Z180_CNTLA1),A ; WRITE TO CNTLA REGISTER
- LD A,C ; FINAL CNTLB VALUE TO ACCUM
- OUT0 (Z180_CNTLB1),A ; WRITE TO CNTLA REGISTER
-;
- LD (ASCI1_CONFIG),DE ; RECORD UPDATED CONFIG
+ LD H,B ; H := CNTLA VAL
+ LD L,C ; L := CNTLB VAL
+ LD B,0 ; MSB OF PORT MUST BE ZERO!
+ LD C,(IY+3) ; GET ASCI BASE REG (CNTLA)
+ OUT (C),H ; WRITE CNTLA VALUE
+ INC C ; BUMP TO
+ INC C ; ... CNTLB REG, B IS STILL 0
+ OUT (C),L ; WRITE CNTLB VALUE
+ INC C ; BUMP TO
+ INC C ; ... STAT REG, B IS STILL 0
+#IF (INTMODE > 0)
+ LD A,$08 ; SET RIE BIT ON
+ OUT (C),A ; WRITE STAT REG
+#ENDIF
+ LD A,$0E ; BUMP TO
+ ADD A,C ; ... ASEXT REG
+ LD C,A ; PUT IN C FOR I/O, B IS STILL 0
+ LD A,$66 ; STATIC VALUE FOR ASEXT
+ OUT (C),A ; WRITE ASEXT REG
+;
+#IF (INTMODE > 0)
+;
+ ; RESET THE RECEIVE BUFFER
+ LD E,(IY+6)
+ LD D,(IY+7) ; DE := _CNT
+ XOR A ; A := 0
+ LD (DE),A ; _CNT = 0
+ INC DE ; DE := ADR OF _HD
+ PUSH DE ; SAVE IT
+ INC DE
+ INC DE
+ INC DE
+ INC DE ; DE := ADR OF _BUF
+ POP HL ; HL := ADR OF _HD
+ LD (HL),E
+ INC HL
+ LD (HL),D ; _HD := _BUF
+ INC HL
+ LD (HL),E
+ INC HL
+ LD (HL),D ; _TL := _BUF
+;
+#ENDIF
+;
XOR A ; SIGNAL SUCCESS
RET ; DONE
;
-ASCI1_QUERY:
- LD DE,(ASCI1_CONFIG)
- XOR A
- RET
+ASCI_INITFAIL:
+ OR $FF ; SIGNAL FAILURE
+ RET ; RETURN
+;
+;
+;
+ASCI_QUERY:
+ LD E,(IY+4) ; FIRST CONFIG BYTE TO E
+ LD D,(IY+5) ; SECOND CONFIG BYTE TO D
+ XOR A ; SIGNAL SUCCESS
+ RET ; DONE
;
-ASCI1_DEVICE:
+;
+;
+ASCI_DEVICE:
LD D,CIODEV_ASCI ; D := DEVICE TYPE
- LD E,1 ; E := PHYSICAL UNIT
+ LD E,(IY) ; E := PHYSICAL UNIT
+ LD C,$00 ; C := DEVICE TYPE, 0x00 IS RS-232
XOR A ; SIGNAL SUCCESS
RET
;
-; LOCAL DATA
-;
-ASCI0_CONFIG .DW DEFSERCFG ; SAVED CONFIG FOR ASCI0
-ASCI1_CONFIG .DW DEFSERCFG ; SAVED CONFIG FOR ASCI1
+; ASCI DETECTION ROUTINE
+; ALWAYS PRESENT, JUST SAY SO.
+;
+ASCI_DETECT:
+ LD A,(IY+3) ; BASE PORT ADR
+ ADD A,$1A ; BUMP TO ASCI CONSTANT LOW
+ LD C,A ; PUT IN C
+ LD B,0 ; MSB FOR 16 BIT I/O
+ XOR A ; ZERO TO ACCUM
+ OUT (C),A ; WRITE TO REG
+ IN A,(C) ; READ IT BACK
+ INC A ; FF -> 0
+ LD A,ASCI_ASCI ; ASSUME ORIG ASCI, NO BRG
+ RET Z ; IF SO, RETURN
+ LD A,ASCI_ASCIB ; MUST BE NEWER ASCI W/ BRG
+ RET ; DONE
;
-; DERIVE A CNTLB VALUE BASED ON AN ENCODED BAUD RATE AND CURRENT CPU SPEED
+; DERIVE CNTLB VALUE BASED ON AN ENCODED BAUD RATE AND CURRENT CPU SPEED
; ENTRY: HL = ENCODED BAUD RATE
; EXIT: C = CNTLB VALUE, A=0/Z IFF SUCCESS
;
@@ -421,24 +601,21 @@ ASCI1_CONFIG .DW DEFSERCFG ; SAVED CONFIG FOR ASCI1
; DUE TO ENCODING BAUD IS ALWAYS DIVISIBLE BY 75
; Z180 DIVISOR IS ALWAYS A FACTOR OF 160
;
-; X = CPU_HZ / 160 / 75 ==> SIMPLIFIED ==> X = CPU_KHZ / 12
-; X = X / (BAUD / 75)
-; IF X % 3 == 0, THEN (PS=1, X := X / 3) ELSE PS=0
-; IF X % 4 == 0, THEN (DR=1, X := X / 4) ELSE DR=0
+; X := CPU_HZ / 160 / 75 ==> SIMPLIFIED ==> X := CPU_KHZ / 12
+; X := X / (BAUD / 75)
+; IF X % 3 == 0, THEN (PS := 1, X := X / 3) ELSE PS=0
+; IF X % 4 == 0, THEN (DR := 1, X := X / 4) ELSE DR=0
; SS := LOG2(X)
;
ASCI_CNTLB:
LD DE,1 ; USE DECODE CONSTANT OF 1 TO GET BAUD RATE ALREADY DIVIDED BY 75
CALL DECODE ; DECODE THE BAUDATE INTO DE:HL, DE IS DISCARDED
- ;CALL TSTPT
RET NZ ; ABORT ON ERROR
PUSH HL ; HL HAS (BAUD / 75), SAVE IT
LD HL,(CB_CPUKHZ) ; GET CPU CLK IN KHZ
- ;LD HL,CPUKHZ ; CPU CLK IN KHZ
- ;LD HL,9216 ; *DEBUG*
-
+;
; DUE TO THE LIMITED DIVISORS POSSIBLE WITH CNTLB, YOU PRETTY MUCH
- ; NEED TO USE A CPU SPEED THAT IS A MULTIPLE OF 128KHZ. BELOW, WE
+ ; NEED TO USE A CPU SPEED THAT IS A MULTIPLE OF 128KHZ. BELOW, WE
; ATTEMPT TO ROUND THE CPU SPEED DETECTED TO A MULTIPLE OF 128KHZ
; WITH ROUNDING. THIS JUST MAXIMIZES POSSIBILITY OF SUCCESS COMPUTING
; THE DIVISOR.
@@ -447,25 +624,22 @@ ASCI_CNTLB:
LD A,L ; MOVE TO ACCUM
AND $80 ; STRIP LOW ORDER 7 BITS
LD L,A ; ... AND PUT IT BACK
-
+;
LD DE,12 ; PREPARE TO DIVIDE BY 12
CALL DIV16 ; BC := (CPU_KHZ / 12), REM IN HL, ZF
- ;CALL TSTPT
POP DE ; RESTORE (BAUD / 75)
RET NZ ; ABORT IF REMAINDER
PUSH BC ; MOVE WORKING VALUE
POP HL ; ... BACK TO HL
CALL DIV16 ; BC := X / (BAUD / 75)
- ;CALL TSTPT
RET NZ ; ABORT IF REMAINDER
-;
+;
; DETERMINE PS BIT BY ATTEMPTING DIVIDE BY 3
PUSH BC ; SAVE WORKING VALUE ON STACK
PUSH BC ; MOVE WORKING VALUE
POP HL ; ... TO HL
LD DE,3 ; SETUP TO DIVIDE BY 3
CALL DIV16 ; BC := X / 3, REM IN HL, ZF
- ;CALL TSTPT
POP HL ; HL := PRIOR WORKING VALUE
LD E,0 ; INIT E := 0 AS WORKING CNTLB VALUE
JR NZ,ASCI_CNTLB1 ; DID NOT WORK, LEAVE PS==0, SKIP AHEAD
@@ -474,7 +648,6 @@ ASCI_CNTLB:
POP HL ; ... VALUE TO HL
;
ASCI_CNTLB1:
- ;CALL TSTPT
; DETERMINE DR BIT BY ATTEMPTING DIVIDE BY 4
LD A,L ; LOAD LSB OF WORKING VALUE
AND $03 ; ISOLATE LOW ORDER BITS
@@ -486,7 +659,6 @@ ASCI_CNTLB1:
RR L ; ...
;
ASCI_CNTLB2:
- ;CALL TSTPT
; DETERMINE SS BITS BY RIGHT SHIFTING AND INCREMENTING
LD B,7 ; LOOP COUNTER, MAX VALUE OF SS IS 7
LD C,E ; MOVE WORKING CNTLB VALUE TO C
@@ -505,7 +677,139 @@ ASCI_CNTLB3:
RET NZ ; ABORT IF NOT ZERO
;
ASCI_CNTLB4:
- ;CALL TSTPT
+ XOR A ; SIGNAL SUCCESS
+ RET ; DONE
+;
+; SPECIAL INPUT STATUS CHECK ROUTINE FOR ASCI. IF THE ASCI PORT DETECTS A LINE
+; ERROR (PARITY, OVERRUN, ETC.) IT WILL STALL UNTIL THE ERROR IS EXPLICITY
+; ACKNOWLEDGED. THIS ROUTINE HANDLES ALL OF THAT AND RETURNS WITH A=1 IF CHAR
+; READY, ELSE A=0. ZF SET OR CLEARED.
+;
+ASCI_ICHK:
+ LD A,(IY+3) ; GET ASCI BASE REG
+ ADD A,4 ; Z180 STAT REG OFFSET
+ LD C,A ; PUT IN C FOR I/O
+ LD B,0 ; MSB FOR 16 BIT I/O
+ IN A,(C) ; READ STAT REG
+ PUSH AF ; SAVE STATUS
+ AND $70 ; PARITY, FRAMING, OR OVERRUN ERROR?
+ JR Z,ASCI_ICHK1 ; JUMP AHEAD IF NO ERRORS
+;
+ ; CLEAR ERROR(S) OR NOTHING FURTHER CAN BE RECEIVED!!!
+ LD C,(IY+3) ; GET ASCI BASE REG (CNTLA)
+ LD B,0 ; MSB FOR 16 BIT I/O
+ IN A,(C) ; READ CNTLA
+ RES 3,A ; CLEAR EFR (ERROR FLAG RESET)
+ OUT (C),A ; WRITE UPDATED CNTLA
+;
+ASCI_ICHK1:
+ POP AF ; RESTORE STATUS VALUE
+ AND $80 ; DATA READY?
+ JP Z,CIO_IDLE ; IF NOT, DO IDLE PROCESSING AND RETURN
+ XOR A ; SIGNAL CHAR WAITING
+ INC A ; ... BY SETTING A TO 1
+ RET ; DONE
+;
+;
+;
+ASCI_PRTCFG:
+ ; ANNOUNCE PORT
+ CALL NEWLINE ; FORMATTING
+ PRTS("ASCI$") ; FORMATTING
+ LD A,(IY) ; DEVICE NUM
+ CALL PRTDECB ; PRINT DEVICE NUM
+ PRTS(": IO=0x$") ; FORMATTING
+ LD A,(IY+3) ; GET BASE PORT
+ CALL PRTHEXBYTE ; PRINT BASE PORT
+
+ ; PRINT THE ASCI TYPE
+ CALL PC_SPACE ; FORMATTING
+ LD A,(IY+1) ; GET ASCI TYPE BYTE
+ RLCA ; MAKE IT A WORD OFFSET
+ LD HL,ASCI_TYPE_MAP ; POINT HL TO TYPE MAP TABLE
+ CALL ADDHLA ; HL := ENTRY
+ LD E,(HL) ; DEREFERENCE
+ INC HL ; ...
+ LD D,(HL) ; ... TO GET STRING POINTER
+ CALL WRITESTR ; PRINT IT
+;
+ ; ALL DONE IF NO ASCI WAS DETECTED
+ LD A,(IY+1) ; GET ASCI TYPE BYTE
+ OR A ; SET FLAGS
+ RET Z ; IF ZERO, NOT PRESENT
+;
+ PRTS(" MODE=$") ; FORMATTING
+ LD E,(IY+4) ; LOAD CONFIG
+ LD D,(IY+5) ; ... WORD TO DE
+ CALL PS_PRTSC0 ; PRINT CONFIG
+;
XOR A
RET
;
+;
+;
+ASCI_TYPE_MAP:
+ .DW ASCI_STR_NONE
+ .DW ASCI_STR_ASCI
+ .DW ASCI_STR_ASCIB
+
+ASCI_STR_NONE .DB "$"
+ASCI_STR_ASCI .DB "ASCI$"
+ASCI_STR_ASCIB .DB "ASCI W/BRG$"
+;
+; WORKING VARIABLES
+;
+ASCI_DEV .DB 0 ; DEVICE NUM USED DURING INIT
+;
+#IF (INTMODE == 0)
+;
+ASCI0_RCVBUF .EQU 0
+ASCI1_RCVBUF .EQU 0
+;
+#ELSE
+;
+; RECEIVE BUFFERS
+;
+ASCI0_RCVBUF:
+ASCI0_BUFCNT .DB 0 ; CHARACTERS IN RING BUFFER
+ASCI0_HD .DW ASCI0_BUF ; BUFFER HEAD POINTER
+ASCI0_TL .DW ASCI0_BUF ; BUFFER TAIL POINTER
+ASCI0_BUF .FILL 32,0 ; RECEIVE RING BUFFER
+ASCI0_BUFEND .EQU $ ; END OF BUFFER
+ASCI0_BUFSZ .EQU $ - ASCI0_BUF ; SIZE OF RING BUFFER
+;
+ASCI1_RCVBUF:
+ASCI1_BUFCNT .DB 0 ; CHARACTERS IN RING BUFFER
+ASCI1_HD .DW ASCI1_BUF ; BUFFER HEAD POINTER
+ASCI1_TL .DW ASCI1_BUF ; BUFFER TAIL POINTER
+ASCI1_BUF .FILL 32,0 ; RECEIVE RING BUFFER
+ASCI1_BUFEND .EQU $ ; END OF BUFFER
+ASCI1_BUFSZ .EQU $ - ASCI1_BUF ; SIZE OF RING BUFFER
+;
+#ENDIF
+;
+; ASCI PORT TABLE
+;
+ASCI_CFG:
+;
+ASCI0_CFG:
+ ; ASCI MODULE A CONFIG
+ .DB 0 ; DEVICE NUMBER (SET DURING INIT)
+ .DB 0 ; ASCI TYPE (SET DURING INIT)
+ .DB 0 ; MODULE ID
+ .DB ASCI0_BASE ; BASE PORT
+ .DW ASCI0CFG ; LINE CONFIGURATION
+ .DW ASCI0_RCVBUF ; POINTER TO RCV BUFFER STRUCT
+;
+ASCI_CFGSIZ .EQU $ - ASCI_CFG ; SIZE OF ONE CFG TABLE ENTRY
+;
+ASCI1_CFG:
+ ; ASCI MODULE B CONFIG
+ .DB 0 ; DEVICE NUMBER (SET DURING INIT)
+ .DB 0 ; ASCI TYPE (SET DURING INIT)
+ .DB 1 ; MODULE ID
+ .DB ASCI1_BASE ; BASE PORT
+ .DW ASCI1CFG ; LINE CONFIGURATION
+ .DW ASCI1_RCVBUF ; POINTER TO RCV BUFFER STRUCT
+;
+ASCI_CFGCNT .EQU ($ - ASCI_CFG) / ASCI_CFGSIZ
diff --git a/Source/HBIOS/cfg_master.asm b/Source/HBIOS/cfg_master.asm
index ed5dec9e..1b30e678 100644
--- a/Source/HBIOS/cfg_master.asm
+++ b/Source/HBIOS/cfg_master.asm
@@ -85,6 +85,8 @@ UARTMFP .EQU FALSE ; UART: AUTO-DETECT MF/PIC UART
UART4 .EQU FALSE ; UART: AUTO-DETECT 4UART UART
;
ASCIENABLE .EQU FALSE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM)
+ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG
+ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG
;
ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM)
ACIADEBUG .EQU FALSE ; ACIA: ENABLE DEBUG OUTPUT
diff --git a/Source/HBIOS/cfg_mk4.asm b/Source/HBIOS/cfg_mk4.asm
index de970391..b371a112 100644
--- a/Source/HBIOS/cfg_mk4.asm
+++ b/Source/HBIOS/cfg_mk4.asm
@@ -71,6 +71,8 @@ UARTMFP .EQU FALSE ; UART: AUTO-DETECT MF/PIC UART
UART4 .EQU TRUE ; UART: AUTO-DETECT 4UART UART
;
ASCIENABLE .EQU TRUE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM)
+ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG
+ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG
;
ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM)
;
diff --git a/Source/HBIOS/cfg_n8.asm b/Source/HBIOS/cfg_n8.asm
index cc9778fd..86fab36f 100644
--- a/Source/HBIOS/cfg_n8.asm
+++ b/Source/HBIOS/cfg_n8.asm
@@ -74,6 +74,8 @@ UARTMFP .EQU FALSE ; UART: AUTO-DETECT MF/PIC UART
UART4 .EQU TRUE ; UART: AUTO-DETECT 4UART UART
;
ASCIENABLE .EQU TRUE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM)
+ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG
+ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG
;
ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM)
;
diff --git a/Source/HBIOS/cfg_rcz180.asm b/Source/HBIOS/cfg_rcz180.asm
index 5987a61b..3eb86317 100644
--- a/Source/HBIOS/cfg_rcz180.asm
+++ b/Source/HBIOS/cfg_rcz180.asm
@@ -62,6 +62,8 @@ DSRTCCHG .EQU FALSE ; DSRTC: FORCE BATTERY CHARGE ON (USE WITH CAUTION!!!)
UARTENABLE .EQU FALSE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM)
;
ASCIENABLE .EQU TRUE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM)
+ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG
+ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG
;
ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM)
;
diff --git a/Source/HBIOS/cfg_sc126.asm b/Source/HBIOS/cfg_sc126.asm
index 10624ad6..d897fcda 100644
--- a/Source/HBIOS/cfg_sc126.asm
+++ b/Source/HBIOS/cfg_sc126.asm
@@ -57,6 +57,8 @@ DSRTCCHG .EQU FALSE ; DSRTC: FORCE BATTERY CHARGE ON (USE WITH CAUTION!!!)
UARTENABLE .EQU FALSE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM)
;
ASCIENABLE .EQU TRUE ; ASCI: ENABLE Z180 ASCI SERIAL DRIVER (ASCI.ASM)
+ASCI0CFG .EQU DEFSERCFG ; ASCI 0: SERIAL LINE CONFIG
+ASCI1CFG .EQU DEFSERCFG ; ASCI 1: SERIAL LINE CONFIG
;
ACIAENABLE .EQU FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM)
;
diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm
index d3dad664..8ce3088b 100644
--- a/Source/HBIOS/hbios.asm
+++ b/Source/HBIOS/hbios.asm
@@ -969,7 +969,7 @@ HB_START1: ; BNKCALL ARRIVES HERE, BUT NOW RUNNING IN RAM BANK
; THIS CODE IS DERIVED FROM UNA BY JOHN COFFMAN
;
; 0: Z80
-; 1: Z80180 - ORIGINAL Z180 IDENTICAL TO HD64180
+; 1: Z80180 - ORIGINAL Z180 (EQUIVALENT TO HD64180)
; 2: Z8S180 - ORIGINAL S-CLASS, REV. K, AKA SL1960, NO ASCI BRG
; 3: Z8S180 - REVISED S-CLASS, REV. N, W/ ASCI BRG
;
@@ -992,8 +992,10 @@ HB_START1: ; BNKCALL ARRIVES HERE, BUT NOW RUNNING IN RAM BANK
INC L ; FLAG Z8S180 REV K (SL1960) OR BETTER
;
; TEST FOR NEWER S-CLASS (REV N)
+ ; ON OLDER S-CLASS, ASCI TIME CONSTANT REG DOES NOT EXIST
+ ; AND WILL ALWYAS READ BACK AS $FF
OUT0 (Z180_ASTC1L),D ; D = 0 AT THIS POINT
- IN0 A,(Z180_ASTC1L) ; COUNTER REG
+ IN0 A,(Z180_ASTC1L) ; ASCI TIME CONSTANT REG
INC A ; FF -> 0
JR Z,HB_CPU1
INC L ; FLAG Z8S180 REV N W/ ASCI BRG
diff --git a/Source/HBIOS/hbios.inc b/Source/HBIOS/hbios.inc
index 50e06531..6eeeae25 100644
--- a/Source/HBIOS/hbios.inc
+++ b/Source/HBIOS/hbios.inc
@@ -92,8 +92,9 @@ CIODEV_PRPCON .EQU $30
CIODEV_PPPCON .EQU $40
CIODEV_SIO .EQU $50
CIODEV_ACIA .EQU $60
-CIODEV_CONSOLE .EQU $D0
CIODEV_PIO .EQU $70
+CIODEV_UF .EQU $80
+CIODEV_CONSOLE .EQU $D0
;
; SUB TYPES OF CHAR DEVICES
;
diff --git a/Source/HBIOS/sio.asm b/Source/HBIOS/sio.asm
index 9a6abaae..1d3d8791 100644
--- a/Source/HBIOS/sio.asm
+++ b/Source/HBIOS/sio.asm
@@ -134,15 +134,12 @@ SIO_PREINIT2:
;
#IF (INTMODE >= 1)
; SETUP INT VECTORS AS APPROPRIATE
- LD A,(SIO_DEV) ; GET NEXT DEVICE NUM
+ LD A,(SIO_DEV) ; GET DEVICE COUNT
OR A ; SET FLAGS
JR Z,SIO_PREINIT3 ; IF ZERO, NO SIO DEVICES, ABORT
;
#IF (INTMODE == 1)
; ADD IM1 INT CALL LIST ENTRY
- LD A,(SIO_DEV) ; GET NEXT DEVICE NUM
- OR A ; SET FLAGS
- JR Z,SIO_PREINIT3 ; IF ZERO, NO SIO DEVICES
LD HL,SIO_INT ; GET INT VECTOR
CALL HB_ADDIM1 ; ADD TO IM1 CALL LIST
#ENDIF
@@ -214,7 +211,7 @@ SIO_INIT1:
;
#IF (INTMODE > 0)
;
-; IM0 ENTRY POINT
+; IM1 ENTRY POINT
;
SIO_INT:
; CHECK/HANDLE FIRST CARD (SIO0) IF IT EXISTS
@@ -232,7 +229,7 @@ SIO_INT:
;
RET ; DONE
;
-; IM1 ENTRY POINTS
+; IM2 ENTRY POINTS
;
SIO_INT0:
; INTERRUPT HANDLER FOR FIRST SIO (SIO0)
diff --git a/Source/HBIOS/uf.asm b/Source/HBIOS/uf.asm
index e12969b5..4e2d7ce5 100644
--- a/Source/HBIOS/uf.asm
+++ b/Source/HBIOS/uf.asm
@@ -149,7 +149,7 @@ UF_QUERY:
; USB-FIFO WILL APPEAR AS A SERIAL DEVICE
;
UF_DEVICE:
- LD D,CIODEV_SIO ; D := DEVICE TYPE
+ LD D,CIODEV_UF ; D := DEVICE TYPE
XOR A ; SIGNAL SUCCESS
LD E,A ; E := PHYSICAL UNIT, ALWAYS 0
LD C,A ; C := DEVICE TYPE, 0x00 IS RS-232