diff options
author | Sungho Park <chywoo.park@samsung.com> | 2012-02-27 21:19:31 +0900 |
---|---|---|
committer | Sungho Park <chywoo.park@samsung.com> | 2012-02-27 21:19:31 +0900 |
commit | deaf05fbd0e3d4b53bcae8514a762cac4f971ac9 (patch) | |
tree | a8653ed627c487711a30ef763b655e79f40b0cda | |
download | vgabios-deaf05fbd0e3d4b53bcae8514a762cac4f971ac9.tar.gz vgabios-deaf05fbd0e3d4b53bcae8514a762cac4f971ac9.tar.bz2 vgabios-deaf05fbd0e3d4b53bcae8514a762cac4f971ac9.zip |
Initialize
34 files changed, 12971 insertions, 0 deletions
@@ -0,0 +1,3 @@ +Not all the functions have been implemented yet. + +Please report any bugs to <info@vruppert.de> @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..dbaed5d --- /dev/null +++ b/ChangeLog @@ -0,0 +1,1311 @@ +2009-04-07 20:18 vruppert + + * vgabios.c (1.69): + + - biosfn_write_teletype: fixed attribute when scrolling in text mode + +2009-04-06 20:17 vruppert + + * ChangeLog (1.28), README (1.17): + + - preparing for release 0.6c + +2009-01-25 16:46 vruppert + + * vbe.c (1.62), vbe.h (1.28), vbetables-gen.c (1.5): + + - added support for a lot more non-standard VBE modes (e.g. widescreen modes) + - requires latest Bochs VBE code (16 MB video memory, VBE_DISPI_ID5, VRAM size + in 64k pages stored in VBE register) + - check if VBE mode is supported with current VRAM size + +2009-01-24 11:02 vruppert + + * clext.c (1.14), vbe.c (1.61), vgabios.c (1.68): + + - use VBE LFB address from PCI base address if present (rewrite of the cirrus + specific function in main vgabios code) + - removed unnecessary spaces + +2008-12-14 09:29 vruppert + + * clext.c (1.13): + + - added DPMS support to cirrus vgabios (patch from Gleb Natapov) + +2008-05-30 17:28 vruppert + + * README (1.16): + + - updated for release 0.6b + +2008-05-22 12:55 vruppert + + * ChangeLog (1.27), README (1.15): + + - preparations for release 0.6b + +2008-05-11 08:40 vruppert + + * biossums.c (1.6): + + - fixed a warning + +2008-03-02 08:47 vruppert + + * vbe.c (1.60): + + - added debug message for unsupported VBE modes + +2008-02-24 09:18 vruppert + + * vbe.c (1.59): + + - in LFB modes the number of banks must be set to 1 + +2008-01-27 10:44 vruppert + + * Makefile (1.21), biossums.c (1.5), vgabios.c (1.67): + + - added PCI data structure for the Cirrus VGABIOS images + - added support for the PCI data structure in biossums + - updated year in copyright + +2008-01-26 11:46 vruppert + + * BUGS (1.4), Makefile (1.20), README (1.14), TODO (1.13), vbe_display_api.txt (1.14): + + - whitespace cleanup + +2006-11-26 10:43 vruppert + + * Makefile (1.19): + + - disable the generation of linemarkers by the preprocessor, since the latest + versions of bcc don't like them + +2006-09-02 13:15 vruppert + + * biossums.c (1.4): + + - the biossums utility no longer modifies VGABIOS images with proper checksum + and size + +2006-08-19 14:28 vruppert + + * Changelog (1.26), README (1.13), TODO (1.12): + + - updates for 0.6a release + +2006-08-19 09:39 vruppert + + * vbe.c (1.58): + + - improved VGA compatible setup for VBE modes (disable CGA and Hercules + compatible memory layout) + +2006-08-18 20:39 vruppert + + * vbe.c (1.57): + + - improved VGA compatible setup for >=8bpp VBE modes (CRTC doubleword mode and + GRDC shift register setting added) + - now using symbolic name for CRTC address register + +2006-08-15 20:42 vruppert + + * vbe.c (1.56), vbetables-gen.c (1.4): + + - init 4bpp VBE modes by a temporary switch to VGA mode 0x6A + - all 4bpp VBE modes now enabled + +2006-08-14 20:24 vruppert + + * vbe.c (1.55): + + - VGA compatible setup for VBE modes improved (Bochs hack can be removed now) + +2006-08-12 07:51 vruppert + + * .cvsignore (1.1): + + - .cvsignore added for auto-generated file + +2006-08-12 07:47 vruppert + + * vbe.c (1.54), vbe.h (1.27), vbe_display_api.txt (1.13), vbetables-gen.c (1.3): + + - cleaned up VBE memory size definitions (removed duplicate defines, main + definition now in vbetables-gen.c) + +2006-08-09 21:28 vruppert + + * vbetables.h (1.30): + + - removed auto-generated file + +2006-08-09 21:26 vruppert + + * vbe.c (1.53), vbe.h (1.26), vbe_display_api.txt (1.12), vbetables-gen.c (1.2), + vbetables.h (1.29): + + - VBE video memory increased to 8 MB + - VBE dispi ID changed to B0C4 + - documentation update + +2006-07-11 08:03 vruppert + + * Makefile (1.18), vbetables-gen.c (1.1), vbetables.h (1.28): + + - generate vbetables.h dynamicly + * initial patch from the qemu project by Fabrice Bellard + * only add modes that fit in video memory (still 4 MB) + * several other fixes (e.g. 4 bpp specific stuff, number of pages) + +2006-07-10 07:47 vruppert + + * vgabios.c (1.66): + + - biosfn_scroll(): check variable 'i' for underflowing when scrolling downwards + to avoid screen corruption + +2006-07-10 07:47 vruppert + + * vbe.c (1.52): + + - VBE set bank functions failure handling added + - VBE get/set logical scan line length fixes for the 4bpp mode + +2006-07-08 13:27 vruppert + + * vbe.c (1.51), vbetables.h (1.27): + + - added special case for the 4 bpp when setting VBE display start + - VBE mode table fixes + +2006-07-07 13:30 vruppert + + * clext.c (1.12): + + - bank pointer must be set to 0 after a mode set + +2006-06-21 16:58 vruppert + + * vbe.c (1.50), vbetables.h (1.26): + + - improved VBE display capabilities check (X resulution checked now) + - removed obsolete defines (LFB always available, always generate dynamic list) + - CR/LF to LF fixes + +2006-06-18 15:22 vruppert + + * clext.c (1.11), vbe.c (1.49), vbe.h (1.25), vbetables.h (1.25), vgabios.c + (1.65): + + - applied patch from the qemu project (Fabrice Bellard) + * Cirrus SVGA now supports the "no clear" bit when switching to Cirrus or + VESA mode + * Bochs VBE protected mode interface improved + * save/restore video state support for Bochs VBE and standard VGA added + * Bochs VBE prepared for more modi + +2006-03-25 10:19 vruppert + + * clext.c (1.10), vgabios.c (1.64), vgatables.h (1.10): + + - applied patch from Fabrice Bellard + * added minimal support for the video parameter table (VPT) + * added Cirrus SVGA mode 0x7b (1600x1200x8) + +2005-12-26 19:50 vruppert + + * vbe.c (1.48), vgabios.c (1.63): + + - Bochs VBE protected mode interface added (based on a patch by malc@pulsesoft.com) + +2005-12-26 19:50 vruppert + + * biossums.c (1.3): + + - biossums utility now supports VGABIOS sizes up to 64 kBytes + +2005-09-21 18:45 vruppert + + * vgatables.h (1.9): + + - mode 0x11: all color planes must be enabled in this 2-color VGA mode + +2005-08-30 18:41 vruppert + + * biossums.c (1.2): + + - missing license text added in biossums.c + +2005-07-02 18:39 vruppert + + * vgabios.c (1.62): + + - BIOS configuration word usually reports initial mode 80x25 color text + - vgabios function 0x0e (write teletype): linefeed (0x0a) only increments the + cursor row value + +2005-05-24 16:50 vruppert + + * vbe.c (1.47), vgabios.c (1.61): + + - output to the vgabios info port can be disabled now. It is still enabled by + default and always possible in debug mode. (based on a patch from Alex Beregszaszi) + +2005-05-20 16:06 vruppert + + * vbe.c (1.46), vgabios.c (1.60): + + - fixed return value for the default case in the VBE section (non-debug mode) + - removed unused macros HALT and PANIC_PORT + +2005-03-07 20:39 vruppert + + * README (1.9): + + - updates for 0.5a release + +2005-03-06 13:06 vruppert + + * Makefile (1.17): + + - vgabios files with cirrus support added to release target + +2005-03-06 12:24 vruppert + + * Makefile (1.16): + + - cross compilation support added (patch from Alex Beregszaszi) + +2005-03-05 13:03 vruppert + + * BUGS (1.3), README (1.8), TODO (1.11): + + - documentation updates + +2004-12-04 15:26 vruppert + + * VGABIOS-lgpl-latest.bin (1.61), VGABIOS-lgpl-latest.cirrus.bin + (1.13), VGABIOS-lgpl-latest.cirrus.debug.bin (1.13), + VGABIOS-lgpl-latest.debug.bin (1.61), clext.c (1.9): + + - Cirrus extension: support for 1280x1024x15 and 1280x1024x16 modes added (patch + from Fabrice Bellard) + +2004-08-08 16:53 vruppert + + * VGABIOS-lgpl-latest.bin (1.60), VGABIOS-lgpl-latest.cirrus.bin (1.12), + VGABIOS-lgpl-latest.cirrus.debug.bin (1.12), + VGABIOS-lgpl-latest.debug.bin (1.60), clext.c (1.8): + + - use single bank mode for VBE + - enable 16k granularity for VBE only + +2004-07-30 19:33 vruppert + + * VGABIOS-lgpl-latest.bin (1.59), VGABIOS-lgpl-latest.cirrus.bin (1.11), + VGABIOS-lgpl-latest.cirrus.debug.bin (1.11), + VGABIOS-lgpl-latest.debug.bin (1.59), clext.c (1.7): + + - cirrus init: set standard vga mode and reset bitblt + +2004-07-22 18:38 vruppert + + * VGABIOS-lgpl-latest.bin (1.58), VGABIOS-lgpl-latest.cirrus.bin (1.10), + VGABIOS-lgpl-latest.cirrus.debug.bin (1.10), + VGABIOS-lgpl-latest.debug.bin (1.58), clext.c (1.6), vbe.c (1.45), + vbetables.h (1.24): + + - cirrus extension: tables for mode 1280x1024x8 added + - vbe: dispi_set_xres() and dispi_set_virt_width() now modify vga compatible + registers + - vbe: mode list entry for mode 800x600x4 fixed + +2004-07-18 20:23 vruppert + + * VGABIOS-lgpl-latest.bin (1.57), VGABIOS-lgpl-latest.cirrus.bin (1.9), + VGABIOS-lgpl-latest.cirrus.debug.bin (1.9), + VGABIOS-lgpl-latest.debug.bin (1.57), vgabios.c (1.59), vgatables.h (1.8): + + - disable CRTC write protection before setting new values + - CRTC line for mode 0x6a fixed + +2004-07-07 16:08 vruppert + + * Makefile (1.15), VGABIOS-lgpl-latest.bin (1.56), + VGABIOS-lgpl-latest.cirrus.bin (1.8), VGABIOS-lgpl-latest.cirrus.debug.bin (1.8), + VGABIOS-lgpl-latest.debug.bin (1.56), biossums.c (1.1), clext.c (1.5): + + - biossums utility for the Bochs BIOS adapted for the LGPL'd VGABIOS + - VESA3 PMINFO checksum calculated in the source + - 24 bpp mode entries fixed (patch from Fabrice Bellard) + +2004-06-25 18:28 vruppert + + * VGABIOS-lgpl-latest.cirrus.bin (1.7), VGABIOS-lgpl-latest.cirrus.debug.bin (1.7), + clext.c (1.4): + + - 4MB memory probe added (patch from Fabrice Bellard) + +2004-06-25 17:31 vruppert + + * VGABIOS-lgpl-latest.bin (1.55), VGABIOS-lgpl-latest.cirrus.bin (1.6), + VGABIOS-lgpl-latest.cirrus.debug.bin (1.6), + VGABIOS-lgpl-latest.debug.bin (1.55), clext.c (1.3): + + - fixed value of sequencer reset register in cirrus mode table + - fixed possible overflow error if cirrus start address is >256k + +2004-06-23 21:11 vruppert + + * VGABIOS-lgpl-latest.bin (1.54), VGABIOS-lgpl-latest.cirrus.bin (1.5), + VGABIOS-lgpl-latest.cirrus.debug.bin (1.5), + VGABIOS-lgpl-latest.debug.bin (1.54), clext.c (1.2): + + - applied new patch for the cirrus extension from suzu + * enable VESA LFB support if a Cirrus PCI adapter is detected + * prepared VBE3 protected mode info block (test case required) + - added VBE functions 4F06h and 4F07h + - some bugfixes + +2004-06-17 18:57 vruppert + + * Makefile (1.14), VGABIOS-lgpl-latest.bin (1.53), + VGABIOS-lgpl-latest.cirrus.bin (1.2), VGABIOS-lgpl-latest.cirrus.debug.bin (1.2), + VGABIOS-lgpl-latest.debug.bin (1.53): + + - fixed makefile targets for the binaries with cirrus extension + +2004-06-16 21:11 vruppert + + * Makefile (1.13), VGABIOS-lgpl-latest.bin (1.52), + VGABIOS-lgpl-latest.cirrus.bin (1.1), VGABIOS-lgpl-latest.cirrus.debug.bin (1.1), + VGABIOS-lgpl-latest.debug.bin (1.52), clext.c (1.1), vgabios.c (1.58): + + - applied suzu's cirrus extension patch. Cirrus SVGA detection, most of the + cirrus-specific modes and some basic VBE features are present now. + +2004-05-31 21:15 vruppert + + * VGABIOS-lgpl-latest.bin (1.51), VGABIOS-lgpl-latest.debug.bin (1.51), + vgabios.c (1.57): + + - write character in planar graphics modes: sequencer map mask must be 0x0f and + bit operation must be 'replace' if bit 7 of attribute is clear + - read/write pixel in planar graphics modes: bit mask setup simplified + +2004-05-11 18:08 vruppert + + * VGABIOS-lgpl-latest.bin (1.50), VGABIOS-lgpl-latest.debug.bin (1.50), + vgabios.c (1.56): + + - biosfn_select_vert_res rewritten in assembler + - scroll text in planar graphics modes: attribute for blank line fixed + - write character in planar graphics modes: graphics controller values fixed + +2004-05-09 20:32 vruppert + + * VGABIOS-lgpl-latest.bin (1.49), VGABIOS-lgpl-latest.debug.bin (1.49), + vbe.c (1.44), vbe.h (1.24), vgabios.c (1.55): + + - VBE init code and some dispi ioport functions rewritten in assembler + - text scroll functions for CGA graphics modes added + - scroll text in graphics modes: attribute for blank line fixed + +2004-05-08 16:06 vruppert + + * BUGS (1.2), README (1.7), TODO (1.10), VGABIOS-lgpl-latest.bin (1.48), + VGABIOS-lgpl-latest.debug.bin (1.48), vbe.c (1.43), vbe.h (1.23), + vbe_display_api.txt (1.11), vgabios.c (1.54): + + - VBE internal functions dispi_set_enable and dispi_set_bank now called both from C + and asm code + - VBE function 0x03 rewritten in assembler + - VBE function 0x08 cleaned up + - text output and scroll functions for graphics modes rewritten using case + structures + - documentation and comments updated + +2004-05-06 21:18 vruppert + + * VGABIOS-lgpl-latest.bin (1.47), VGABIOS-lgpl-latest.debug.bin (1.47), + vbe.c (1.42), vbe.h (1.22), vgabios.c (1.53): + + - VBE functions 0x05, 0x06, 0x07 and some dispi ioport functions rewritten in + assembler + - VBE functions 0x06 and 0x07: get functions now supported, 15 bpp bug fixed + +2004-05-05 19:24 vruppert + + * VGABIOS-lgpl-latest.bin (1.46), VGABIOS-lgpl-latest.debug.bin (1.46), + vbe.c (1.41), vbe.h (1.21), vbe_display_api.txt (1.10), vgabios.c (1.52): + + - 8 bit DAC capability flag set + - vbe_biosfn_set_get_dac_palette_format implemented + - VBE api description updated + - C definitions from header files now used assembler code + +2004-05-02 17:27 vruppert + + * VGABIOS-lgpl-latest.bin (1.45), VGABIOS-lgpl-latest.debug.bin (1.45), + vgabios.c (1.51): + + - text scroll functions for PLANAR1/PLANAR4 graphics modes added + - function biosfn_get_ega_info rewritten in assembler + - read/write graphics pixel functions rewritten using a case structure + +2004-05-01 16:03 vruppert + + * VGABIOS-lgpl-latest.bin (1.44), VGABIOS-lgpl-latest.debug.bin (1.44), + vgabios.c (1.50): + + - biosfn_enable_cursor_emulation rewritten in assembler + - remap of the cursor shape depends on modeset control bit 0 + - text output in PLANAR4 modes now supports attribute bit 7 (XOR with background) + +2004-04-25 20:13 vruppert + + * VGABIOS-lgpl-latest.bin (1.43), VGABIOS-lgpl-latest.debug.bin (1.43), + vgabios.c (1.49), vgatables.h (1.7): + + - table entries for vga mode 0x0f fixed (PLANAR2 exists on EGA only) + - function release_font_access now supports the monochrome text mode + - PLANAR1 modes now supported in text output functions and read/write pixel + - function AH=0x12/BL=0x32 rewritten in assembler + +2004-04-25 08:45 vruppert + + * VGABIOS-lgpl-latest.bin (1.42), VGABIOS-lgpl-latest.debug.bin (1.42), + vgabios.c (1.48): + + - block address calculation in font functions fixed + - functions AX=0x1103, AH=0x12/BL=0x31 and AH=0x12/BL=0x33 rewritten in assembler + +2004-04-24 09:59 vruppert + + * VGABIOS-lgpl-latest.bin (1.41), VGABIOS-lgpl-latest.debug.bin (1.41), + vgabios.c (1.47): + + - read/write graphics pixel for PLANAR4 modes added + - CGA specific functions (group AH = 0x0B) implemented + +2004-04-23 14:34 vruppert + + * VGABIOS-lgpl-latest.bin (1.40), VGABIOS-lgpl-latest.debug.bin (1.40), + vgabios.c (1.46): + + - remaining palette and dac read/write functions (except gray scale summing) + rewritten in assembler + +2004-04-18 13:43 vruppert + + * VGABIOS-lgpl-latest.bin (1.39), VGABIOS-lgpl-latest.debug.bin (1.39), + vgabios.c (1.45): + + - some palette and dac read/write functions rewritten in assembler + - main int10 debug message now works with assembler functions, too + +2004-04-18 09:15 japj + + * vbe.c (1.40): + + updated my email address + put vgabios url in the bios copyright string + (instead of my old email address) + +2004-04-17 07:18 vruppert + + * VGABIOS-lgpl-latest.bin (1.38), VGABIOS-lgpl-latest.debug.bin (1.38), + vgabios.c (1.44): + + - biosfn_set_video_mode: don't load DAC registers if default palette loading is + disabled. Perform gray scale summing if enabled. + - biosfn_perform_gray_scale_summing: switch between DAC read and write mode is + required to make this function work. Maximum DAC value always set to 0x3f. + +2004-04-08 17:50 vruppert + + * VGABIOS-lgpl-latest.bin (1.37), VGABIOS-lgpl-latest.debug.bin (1.37), + vgabios.c (1.43): + + - write character function for the LINEAR8 mode + - get_font_access() and release_font_access() rewritten in assembler + - fixed wrong variable name in the init code + +2004-04-06 19:31 vruppert + + * VGABIOS-lgpl-latest.bin (1.36), VGABIOS-lgpl-latest.debug.bin (1.36), + vgabios.c (1.42): + + - init functions rewitten in assembler + - function biosfn_set_display_code rewritten in assembler + +2004-04-05 19:40 vruppert + + * VGABIOS-lgpl-latest.bin (1.35), VGABIOS-lgpl-latest.debug.bin (1.35), + vgabios.c (1.41): + + - functions biosfn_get_video_mode() and biosfn_read_display_code() rewritten + in assembler + +2004-04-04 18:20 vruppert + + * VGABIOS-lgpl-latest.bin (1.34), VGABIOS-lgpl-latest.debug.bin (1.34), + vgabios.c (1.40): + + - write character function for CGA modes added + - read/write graphics pixel for CGA and LINEAR8 modes added + +2004-02-23 21:08 vruppert + + * VGABIOS-lgpl-latest.bin (1.33), VGABIOS-lgpl-latest.debug.bin (1.33), + vbe.c (1.39): + + - dispi_get_max_bpp(): restore the original value of the vbe enable register + +2004-02-22 14:17 vruppert + + * README (1.6), vbe.c (1.38), vbe.h (1.20), vbe_display_api.txt (1.9), + VGABIOS-lgpl-latest.bin (1.32), VGABIOS-lgpl-latest.debug.bin (1.32): + + - new function dispi_get_max_bpp() returns the bpp capabilities of the Bochs gui + - create the mode list depending on the supported bpp capability + - unused stuff removed + - documentation updated + +2004-02-21 18:20 vruppert + + * vbe.c (1.37), vbe.h (1.19), vbetables.h (1.23), + VGABIOS-lgpl-latest.bin (1.31), VGABIOS-lgpl-latest.debug.bin (1.31): + + - dynamicly genarated vbe mode_info list works now + +2003-11-17 21:04 vruppert + + * vbe.c (1.36), vbetables.h (1.22), vgabios.c (1.39), vgatables.h (1.6), + VGABIOS-lgpl-latest.bin (1.30), VGABIOS-lgpl-latest.debug.bin (1.30): + + - new VBE presence flag stored at unused BDA address 0xB9 + - VBE init code rewritten + - added BIOS TTY flag for VBE mode 0x0102 (TODO: scrolling) + - vgabios_init_func: load and activate text font already done by set_video_mode + - function biosfn_get_all_palette_reg() fixed + +2003-11-06 00:26 cbothamy + + * README (1.5): + + - add changes for 0.4c release + +2003-11-06 00:22 cbothamy + + * VGABIOS-lgpl-latest.bin (1.29), VGABIOS-lgpl-latest.debug.bin + (1.29): + + - compile vgabios.c rev1.38 + +2003-11-06 00:21 cbothamy + + * vgabios.c (1.38): + + - activate char table after loading it when setting a text video + mode + +2003-11-06 00:19 cbothamy + + * Makefile (1.12): + + - when making a release, remove unwanted files first, and exclude + CVS from the tarball + +2003-11-04 22:50 cbothamy + + * ChangeLog (1.20, v0_4b): + + - update ChangeLog for 0.4b release + +2003-11-04 22:49 cbothamy + + * README (1.4, v0_4b): + + - update Changes for 0.4b release + +2003-11-04 20:26 vruppert + + * vgabios.c (1.37), VGABIOS-lgpl-latest.bin (1.28), + VGABIOS-lgpl-latest.debug.bin (1.28) (utags: v0_4b): + + - biosfn_get_font_info(): character height must be returned in CX + +2003-11-03 21:57 vruppert + + * vbe.c (1.35, v0_4b), vgabios.c (1.36), VGABIOS-lgpl-latest.bin + (1.27), VGABIOS-lgpl-latest.debug.bin (1.27): + + - the 'noclearmem' flag is not stored in the 'current video mode' + register (0040h:0049h) - VBE also stores the 'noclear' flag in + the 'video control' register (0040h:0087h) + +2003-10-05 10:06 vruppert + + * vbe.h (1.18, v0_4b), vbe_display_api.txt (1.8, v0_4b), + VGABIOS-lgpl-latest.bin (1.26), VGABIOS-lgpl-latest.debug.bin + (1.26): + + - changed VBE i/o registers to 0x01CE/CF (suggestion from Daniel + Gimpelevich) + +2003-08-18 18:38 vruppert + + * VGABIOS-lgpl-latest.bin (1.25), VGABIOS-lgpl-latest.debug.bin + (1.25), vgabios.c (1.35): + + - wrong offsets to the character tables (INT 0x1F/0x43) fixed + (underscore added) - functions accessing the CRT controller + optimized using a local variable 'crtc_addr' + +2003-08-17 15:46 cbothamy + + * ChangeLog (1.19, v0_4a): + + - ChangeLog is now automatically generated by running "cvs2cl -r + -t -P -S" - update ChangeLog for 0.4a release + +2003-08-17 15:44 cbothamy + + * README (1.3, v0_4a): + + - added the old ChangeLog in the HOSTORY section of the README + file - update History for 0.4a release, with a summary of Changes + +2003-08-17 15:24 cbothamy + + * Makefile (1.11, v0_4b, v0_4a): + + - fix Makefile for "release" target + +2003-08-16 01:49 cbothamy + + * Makefile (1.10), README (1.2), VGABIOS-lgpl-latest.bin (1.24, + v0_4a), VGABIOS-lgpl-latest.debug.bin (1.24, v0_4a), vgabios.c + (1.34, v0_4a): + + - update the Makefile for releases - remove references to old + plex86 website - update the Makefile so it build + VGABIOS-lgpl-latest.bin and VGABIOS-lgpl-latest.debug.bin + +2003-08-07 18:17 vruppert + + * VGABIOS-lgpl-latest.bin (1.23), VGABIOS-lgpl-latest.debug.bin + (1.23): + + - current VBE mode now stored in BDA (unused address 0xBA) + +2003-08-07 17:54 vruppert + + * vbe.c (1.34), vgatables.h (1.5, v0_4b) (utags: v0_4a): + + - current VBE mode now stored in BDA (unused address 0xBA) + +2003-07-20 18:05 vruppert + + * vgabios.c (1.33), VGABIOS-lgpl-latest.bin (1.22), + VGABIOS-lgpl-latest.debug.bin (1.22): + + - fixed a few functions accessing the attribute controller + +2003-07-19 09:33 vruppert + + * vgabios.c (1.32), VGABIOS-lgpl-latest.bin (1.21), + VGABIOS-lgpl-latest.debug.bin (1.21): + + - re-enable video after programming the attribute controller - + biosfn_set_all_palette_reg(): number of palette registers fixed + +2003-07-16 22:32 vruppert + + * ChangeLog (1.18), vbe.c (1.33), vbe.h (1.17, v0_4a), + vbe_display_api.txt (1.7, v0_4a), vgabios.c (1.31), + VGABIOS-lgpl-latest.bin (1.20), VGABIOS-lgpl-latest.debug.bin + (1.20): + + - LFB flag now stored in the register VBE_DISPI_INDEX_ENABLE - + release date in Changelog fixed - release date of VBE BIOS 0.6 + was the same as VGA BIOS 0.3b - year changed in copyright + messages + +2003-07-15 12:40 vruppert + + * VGABIOS-lgpl-latest.bin (1.19), VGABIOS-lgpl-latest.debug.bin + (1.19): + + - new function dispi_get_bpp() - function + vbe_biosfn_set_get_logical_scan_line_length() fixed for >8bpp - + number of image pages of all VBE modes fixed + +2003-07-15 12:35 vruppert + + * vbe.c (1.32), vbetables.h (1.21, v0_4b, v0_4a): + + - new function dispi_get_bpp() - function + vbe_biosfn_set_get_logical_scan_line_length() fixed for >8bpp - + number of image pages of all VBE modes fixed + +2003-07-14 19:45 vruppert + + * vbe_display_api.txt (1.6): + + - description of VBE_DISPI_ interface 0xb0c2 added + +2003-07-10 19:07 vruppert + + * vbe.c (1.31), vbetables.h (1.20), VGABIOS-lgpl-latest.bin (1.18), + VGABIOS-lgpl-latest.debug.bin (1.18): + + - 15 bpp VBE modes added - "Bochs own" mode 0x142 (640x480x32bpp) + added + +2003-07-01 19:00 vruppert + + * vbe.c (1.30), vbe.h (1.16), vbetables.h (1.19), + VGABIOS-lgpl-latest.bin (1.17), VGABIOS-lgpl-latest.debug.bin + (1.17): + + - VBE preserve display memory feature implemented - VBE mode + entries 0x117 and 0x118 added + +2003-06-30 21:27 vruppert + + * vbe.c (1.29), vbe.h (1.15), vbetables.h (1.18), + VGABIOS-lgpl-latest.bin (1.16), VGABIOS-lgpl-latest.debug.bin + (1.16): + + - VBE mode info blocks of modes with >8bpp enabled - VBE modes + with 24 bpp: bytes per scanline fixed - vbe_biosfn_set_mode() now + supports >8bpp - VBE will be enabled with new VBE_DISPI_ID2 + (0xB0C2) + +2003-06-29 12:53 vruppert + + * vbetables.h (1.17), VGABIOS-lgpl-latest.bin (1.15), + VGABIOS-lgpl-latest.debug.bin (1.15): + + - duplicate lines with VBE_MODE_ATTRIBUTE_GRAPHICS_MODE removed - + VBE mode info items of currently unsupported modes fixed + +2003-06-15 21:19 vruppert + + * vgabios.c (1.30), VGABIOS-lgpl-latest.bin (1.14), + VGABIOS-lgpl-latest.debug.bin (1.14): + + - function write_gfx_char() rewritten + +2003-04-26 09:27 vruppert + + * VGABIOS-lgpl-latest.debug.bin (1.13): + + - added missing VBE function dispi_get_bank() - added missing + return codes for VBE function 4F05h - memory size is always + reported in VBE function 4F00h - fixed scan line length for VBE + mode 0102h - fixed function set_active_page() for graphics modes + - fixed the page sizes of some VGA modes + +2003-04-26 09:22 vruppert + + * vbe.c (1.28), vbetables.h (1.16), vgabios.c (1.29), vgatables.h + (1.4), VGABIOS-lgpl-latest.bin (1.13): + + - added missing VBE function dispi_get_bank() - added missing + return codes for VBE function 4F05h - memory size is always + reported in VBE function 4F00h - fixed scan line length for VBE + mode 0102h - fixed function set_active_page() for graphics modes + - fixed the page sizes of some VGA modes + +2003-04-20 09:51 vruppert + + * vgabios.c (1.28), vgatables.h (1.3), VGABIOS-lgpl-latest.bin + (1.12), VGABIOS-lgpl-latest.debug.bin (1.12): + + - function write_gfx_char() now supports different font sizes - + some entries of the static functionality table fixed + +2003-04-18 09:23 vruppert + + * vbe.c (1.27), vbe.h (1.14), vbetables.h (1.15): + + - applied patch #1331 * new function dispi_set_bank_farcall() + * VBE mode info item WinFuncPtr points to the new function if the + flag VBE_WINDOW_ATTRIBUTE_RELOCATABLE is set * flag + VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE added + +2003-02-11 20:17 vruppert + + * VGABIOS-lgpl-latest.bin (1.11), VGABIOS-lgpl-latest.debug.bin + (1.11), vbe.c (1.26), vbetables.h (1.14): + + - VBE mode search rewritten * improved function + mode_info_find_mode() is now used by the VBE functions 0x4F01 + and 0x4F02 * removed all mode list entries with the LFB bit + set. LFB detection is now present in the function + mode_info_find_mode() + +2003-02-09 20:59 vruppert + + * VGABIOS-lgpl-latest.bin (1.10), VGABIOS-lgpl-latest.debug.bin + (1.10), vgabios.c (1.27): + + - function write_gfx_char(): memory address now calculated in + this function; background color is always black - function + biosfn_write_char_attr(): the count parameter is now used in + graphics modes too - function biosfn_write_char_only() works + the same way as function biosfn_write_char_attr() in graphics + mode - copying charmap data optimized using memcpyb() + +2003-02-09 11:36 vruppert + + * VGABIOS-lgpl-latest.bin (1.9), VGABIOS-lgpl-latest.debug.bin + (1.9): + + - VESA mode 0x102 added (uses existing SVGA mode 0x6a) - all VESA + modes with the LFB flag set removed from the list (Linux doesn't + like mode numbers > 0x07ff) + +2003-02-09 11:02 vruppert + + * vbe.c (1.25), vbe.h (1.13), vbetables.h (1.13): + + - VESA mode 0x102 added (uses existing SVGA mode 0x6a) - all VESA + modes with the LFB flag set removed from the list (Linux doesn't + like mode numbers > 0x07ff) + +2003-02-08 13:04 vruppert + + * vbe.c (1.24), vgabios.c (1.26): + + - vbe_biosfn_return_current_mode() now returns the active + standard VGA mode TODO: return VESA mode if enabled - + biosfn_set_video_mode() now clears the screen in CGA mode + correctly - write character functions are now working in all + PLANAR4 graphics modes - added stubs for unimplemented features + in graphics modes + +2003-02-04 22:19 vruppert + + * VGABIOS-lgpl-latest.bin (1.8), VGABIOS-lgpl-latest.debug.bin + (1.8): + + - set video mode: clear vga memory in graphics mode - set video + mode: load default font in text mode - write character + implemented for graphics mode 0x12 + +2003-02-04 22:06 vruppert + + * vgabios.c (1.25): + + - set video mode: clear vga memory in graphics mode - set video + mode: load default font in text mode - write character + implemented for graphics mode 0x12 + +2003-01-21 19:30 vruppert + + * vgabios.c (1.24): + + - remap the cursor size if the char height is > 8 and the new + values are < 8 + +2003-01-20 18:24 cbothamy + + * Makefile (1.9): + + - fix so make -j2 does not overwrite temp files + +2003-01-19 12:35 vruppert + + * vgabios.c (1.23): + + - function set_scan_lines() recalculates the number of rows and + the page size - new values for char height, text rows and page + size are stored in the BIOS data segment - asm helper function + idiv_u added + +2003-01-15 18:49 cbothamy + + * VGABIOS-lgpl-latest.bin (1.7), VGABIOS-lgpl-latest.debug.bin + (1.7): + + - compile vgabios rev 1.22 + +2003-01-15 18:49 cbothamy + + * vgabios.c (1.22): + + - fix bug found by ams : a 8bits index value was compared to + 0x100 in some cases in biosfn_set_all_dac_reg, + biosfn_read_all_dac_reg, biosfn_perform_gray_scale_summing + +2003-01-15 17:34 cbothamy + + * Makefile (1.8): + + - fix symbol table file names, discovered by ams + +2003-01-04 21:20 vruppert + + * VGABIOS-lgpl-latest.bin (1.6), VGABIOS-lgpl-latest.debug.bin + (1.6), vgabios.c (1.21): + + - biosfn_set_video_mode(): reset attribute controller flip-flop + before setting up the controller's registers (bug found with + amidiag) + +2003-01-04 09:50 vruppert + + * vbe.c (1.23): + + - VBE function 0x00 returns VBE 1.x compatible information if no + VBE signature is present + +2003-01-01 12:44 vruppert + + * VGABIOS-lgpl-latest.bin (1.5), VGABIOS-lgpl-latest.debug.bin + (1.5): + + - SVGA mode 0x6A (800x600x4) added to the list of graphics modes + +2002-12-31 18:07 vruppert + + * vgatables.h (1.2): + + - SVGA mode 0x6A (800x600x4) added to the list of graphics modes + +2002-11-23 10:38 cbothamy + + * ChangeLog (1.17, v0_3b): + + - fix changelog for 0.3b release + +2002-10-20 17:12 vruppert + + * VGABIOS-lgpl-latest.bin (1.4), VGABIOS-lgpl-latest.debug.bin + (1.4), vgabios.c (1.20) (utags: v0_3b): + + - new function set_scan_lines() for the font size change (patch + from Hartmut Birr) - cursor shape start and end must be updated + in set_scan_lines() - set_scan_lines() is called by the functions + 0x1110, 0x1111, 0x1112 and 0x1114 after copying the font data + +2002-10-04 08:20 vruppert + + * VGABIOS-lgpl-latest.bin (1.3), VGABIOS-lgpl-latest.debug.bin + (1.3), vgabios.c (1.19): + + - biosfn_set_single_dac_reg(): the red value is stored in DH + +2002-09-19 19:05 cbothamy + + * VGABIOS-lgpl-latest.bin (1.2), VGABIOS-lgpl-latest.debug.bin + (1.2): + + - updated with latest changes + +2002-09-19 19:03 cbothamy + + * ChangeLog (1.16), Makefile (1.7, v0_3b), vbe.c (1.22, v0_3b), + vgabios.c (1.18), vgabios.h (1.3, v0_4b, v0_4a, v0_3b): + + - updated the Makefile - removed display of copyrights. - + changed the Copyright string to "LGPL VGABios developers" + +2002-09-08 21:14 vruppert + + * vgabios.c (1.17): + + - set the cursor shape depending on the current font height - + clear BL before calling int 0x10 function 0x1103 in + vgabios_init_func + +2002-08-23 22:58 cbothamy + + * vbe.c (1.21), vbetables.h (1.12, v0_3b): + + - added lfb-mode numbers (patch from mathis) + +2002-07-21 21:57 japj + + * vbe.c (1.20), vgabios.c (1.16): + + gcc2/3 preprocessing fix + +2002-05-18 16:55 cbothamy + + * vgabios.c (1.15): + + - include patch from Volker that adds some text font functions + +2002-05-01 23:13 japj + + * VGABIOS-lgpl-latest.bin (1.1), VGABIOS-lgpl-latest.debug.bin + (1.1): + + adding latest bin & debug bin of the vgabios + +2002-04-29 14:50 japj + + * ChangeLog (1.15), vbe.c (1.19), vbe.h (1.12, v0_3b), vbetables.h + (1.11), vgabios.c (1.14): + + - applying hw scrolling/multibuffering patch + +2002-04-25 21:59 japj + + * Makefile (1.6), vbe.c (1.18), vgabios.c (1.13): + + - reverting #asm/##asm & endasm patch (does not work with with + cygwin) + +2002-04-19 19:38 japj + + * Makefile (1.5), vbe.c (1.17), vgabios.c (1.12): + + - fixing preprocessing of vgabios with latest gcc (from Mandrake + 8.2) + +2002-04-08 23:44 japj + + * ChangeLog (1.14), vbe_display_api.txt (1.5, v0_3b): + + - preparing docs for new DISPI interface (for hardware scrolling) + +2002-04-03 19:06 japj + + * ChangeLog (1.13), TODO (1.9, v0_4b, v0_4a, v0_3b), vbe.c (1.16): + + - defaulting LFB on + updated changelog & todo + +2002-04-03 00:38 cbothamy + + * vbe.c (1.15), vgabios.c (1.11): + + - changed the logging ports to 0x500 -> 0x502 + +2002-03-14 17:54 japj + + * vbe.c (1.14): + + - vbetables.h is dependant upon some defines (VBE_HAVE_LFB), so + put the include *after* the define + +2002-03-13 21:47 japj + + * ChangeLog (1.12), TODO (1.8), vbe.c (1.13), vbetables.h (1.10), + vgabios.c (1.10): + + - made LFB dependant upon define - not implement vbe functions + return failure - updated todo & docs for things after bochs 1.4 + +2002-03-13 19:46 japj + + * vbe.h (1.11), vbe_display_api.txt (1.4): + + - added max video memory + documented what is in the 0xb0c0 + interface + +2002-03-12 02:33 cbothamy + + * ChangeLog (1.11), Makefile (1.4): + + - updated for 0.3a. Merged vgabios.bin and vbebios.bin + +2002-03-10 21:36 japj + + * ChangeLog (1.10), vbetables.h (1.9): + + - added LFB modes for testing with vbe-lfb patch in Bochs + +2002-03-10 17:42 japj + + * vbe.c (1.12, v0_3a): + + - show people when they do NOT have VBE support available + +2002-03-10 17:36 japj + + * TODO (1.7, v0_3a), vbe.c (1.11), vbe.h (1.10, v0_3a), vgabios.c + (1.9, v0_3a): + + - cleanup of vbe internal functions (set 8bpp mode is now + dependant on ModeInfo content instead of hardcoded functions) + +2002-03-10 17:20 cbothamy + + * ChangeLog (1.9, v0_3a), TODO (1.6): + + - updated for 0.3a + +2002-03-10 17:19 cbothamy + + * vbe.c (1.10), vbe.h (1.9): + + - added vbe_has_vbe_display function that detects an attached vbe + display + +2002-03-10 17:12 cbothamy + + * vgabios.c (1.8): + + - vbe calls are done only if a vbe display is detected + +2002-03-10 11:25 japj + + * vbe.h (1.8), vbe_display_api.txt (1.3, v0_3a): + + - preparing for LFB support + +2002-03-09 14:25 japj + + * vgabios.c (1.7): + + - fixing initial cursor shape to _ instead of - + +2002-03-08 23:08 japj + + * ChangeLog (1.8), TODO (1.5), vbe.c (1.9), vbe.h (1.7), vgabios.c + (1.6): + + - updating vbe code to new API + +2002-03-08 21:48 japj + + * vbe.c (1.8), vbe.h (1.6), vbetables.h (1.8, v0_3a): + + - updating vbe code with #defines from API + +2002-03-08 21:31 japj + + * vbe_display_api.txt (1.2): + + - adding some text about how banks work + +2002-03-08 21:09 japj + + * ChangeLog (1.7), vbe_display_api.txt (1.1): + + - adding vbe_display_api documentation + +2002-03-07 21:36 japj + + * ChangeLog (1.6), vbe.c (1.7), vbetables.h (1.7): + + - added 1024x768xbpp support - some more cleanups/comments + +2002-03-06 21:55 japj + + * ChangeLog (1.5), TODO (1.4), vbe.c (1.6), vbetables.h (1.6), + vgabios.c (1.5): + + - updated changelog with new modi - added 640x480x8 (Mandrake + Installer can use this!) - added pre VBE2 compatible 'detection' + - fixed problem when normal vga set mode wouldn't disable vbe + mode + +2002-03-06 20:59 japj + + * TODO (1.3), vbe.c (1.5), vbe.h (1.5), vbetables.h (1.5), + vgabios.c (1.4): + + - adding 640x400x8 and 800x600x8 vbe support (this depends + HEAVILY on my bochs vga code patch - japj) + +2002-03-06 18:00 japj + + * vbe.c (1.4), vbe.h (1.4), vbetables.h (1.4): + + - implemented banked & lfb support for 320x200x8bpp (some fixes + for vbetest program not displaying anything) + +2002-03-05 20:25 japj + + * Makefile (1.3, v0_3a): + + for vbe debug bios: - print debugging information in assembly + output - print source code in assembly output + +2002-03-01 19:39 japj + + * ChangeLog (1.4), TODO (1.2), vbe.c (1.3), vbe.h (1.3), + vbetables.h (1.3): + + - added vbe support for 320x200x8 using the standard vgamode + (0x13) + +2002-02-19 00:29 japj + + * ChangeLog (1.3): + + - updating ChangeLog with lfbprof + +2002-02-18 23:26 japj + + * tests/lfbprof/: lfbprof.c (1.2), lfbprof.h (1.2) (utags: v0_3a, + v0_3b, v0_4a, v0_4b): + + - fixed unsigned short for mode list (-1 != 0xffff otherwise) - + fixed LfbMapRealPointer macro mask problem (some modes were + skipped) - added some extra 'debugging' printf's + +2002-02-18 23:07 japj + + * tests/lfbprof/: Makefile (1.1, v0_4b, v0_4a, v0_3b, v0_3a), + lfbprof.c (1.1), lfbprof.h (1.1): + + - Adding lfbprof testprogram (for vbe testing purposes) It + needs to be compiled with the Watcom C Compiler + +2002-02-18 18:48 japj + + * vbe.c (1.2), vbe.h (1.2): + + - cosmetic updates to vbe.c/h + added bunch of FIXMEs for work + that needs to be done + +2002-02-18 18:34 japj + + * vbetables.h (1.2): + + - cosmetic updates in vbetables.h + +2002-02-18 18:32 japj + + * ChangeLog (1.2): + + updated changelog with merge of vbebios 0.2 + +2002-02-18 18:07 japj + + * vgabios.c (1.3): + + - small cosmetic cleanup in vgabios vbe code + added FIXMEs + +2002-02-18 17:55 japj + + * Makefile (1.2), dataseghack (1.2, v0_4b, v0_4a, v0_3b, v0_3a), + vbe.c (1.1), vbe.h (1.1), vbetables.h (1.1), vgabios.c (1.2), + vgabios.h (1.2, v0_3a): + + - merging with vbebios 0.2 release + +2002-02-18 11:31 cbothamy + + * BUGS (1.1, v0_4b, v0_4a, v0_3b, v0_3a), COPYING (1.1, v0_4b, + v0_4a, v0_3b, v0_3a), ChangeLog (1.1), Makefile (1.1), Notes + (1.1, v0_4b, v0_4a, v0_3b, v0_3a), README (1.1, v0_3b, v0_3a), + TODO (1.1), dataseghack (1.1), vgabios.c (1.1), vgabios.h (1.1), + vgafonts.h (1.1, v0_4b, v0_4a, v0_3b, v0_3a), vgatables.h (1.1, + v0_3b, v0_3a), tests/testbios.c (1.1, v0_4b, v0_4a, v0_3b, + v0_3a): + + - initial import + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e8c427a --- /dev/null +++ b/Makefile @@ -0,0 +1,87 @@ +SHELL = /bin/sh + +CC = gcc +CFLAGS = -g -O2 -Wall -Wstrict-prototypes +LDFLAGS = + +GCC = gcc +BCC = bcc +AS86 = as86 + +RELEASE = `pwd | sed "s-.*/--"` +RELDATE = `date '+%d %b %Y'` +RELVERS = `pwd | sed "s-.*/--" | sed "s/vgabios//" | sed "s/-//"` + +VGABIOS_DATE = "-DVGABIOS_DATE=\"$(RELDATE)\"" + +all: bios cirrus-bios + + +bios: biossums vgabios.bin vgabios.debug.bin + +cirrus-bios: vgabios-cirrus.bin vgabios-cirrus.debug.bin + +clean: + /bin/rm -f biossums vbetables-gen vbetables.h *.o *.s *.ld86 \ + temp.awk.* vgabios*.orig _vgabios_* _vgabios-debug_* core vgabios*.bin vgabios*.txt $(RELEASE).bin *.bak + +dist-clean: clean + +release: + VGABIOS_VERS=\"-DVGABIOS_VERS=\\\"$(RELVERS)\\\"\" make bios cirrus-bios + /bin/rm -f *.o *.s *.ld86 \ + temp.awk.* vgabios.*.orig _vgabios_.*.c core *.bak .#* + cp VGABIOS-lgpl-latest.bin ../$(RELEASE).bin + cp VGABIOS-lgpl-latest.debug.bin ../$(RELEASE).debug.bin + cp VGABIOS-lgpl-latest.cirrus.bin ../$(RELEASE).cirrus.bin + cp VGABIOS-lgpl-latest.cirrus.debug.bin ../$(RELEASE).cirrus.debug.bin + tar czvf ../$(RELEASE).tgz --exclude CVS -C .. $(RELEASE)/ + +vgabios.bin: vgabios.c vgabios.h vgafonts.h vgatables.h vbe.h vbe.c vbetables.h + $(GCC) -E -P vgabios.c $(VGABIOS_VERS) -DVBE -DPCIBIOS $(VGABIOS_DATE) > _vgabios_.c + $(BCC) -o vgabios.s -C-c -D__i86__ -S -0 _vgabios_.c + sed -e 's/^\.text//' -e 's/^\.data//' vgabios.s > _vgabios_.s + $(AS86) _vgabios_.s -b vgabios.bin -u -w- -g -0 -j -O -l vgabios.txt + rm -f _vgabios_.s _vgabios_.c vgabios.s + mv vgabios.bin VGABIOS-lgpl-latest.bin + ./biossums VGABIOS-lgpl-latest.bin + ls -l VGABIOS-lgpl-latest.bin + +vgabios.debug.bin: vgabios.c vgabios.h vgafonts.h vgatables.h vbe.h vbe.c vbetables.h + $(GCC) -E -P vgabios.c $(VGABIOS_VERS) -DVBE -DPCIBIOS -DDEBUG $(VGABIOS_DATE) > _vgabios-debug_.c + $(BCC) -o vgabios-debug.s -C-c -D__i86__ -S -0 _vgabios-debug_.c + sed -e 's/^\.text//' -e 's/^\.data//' vgabios-debug.s > _vgabios-debug_.s + $(AS86) _vgabios-debug_.s -b vgabios.debug.bin -u -w- -g -0 -j -O -l vgabios.debug.txt + rm -f _vgabios-debug_.s _vgabios-debug_.c vgabios-debug.s + mv vgabios.debug.bin VGABIOS-lgpl-latest.debug.bin + ./biossums VGABIOS-lgpl-latest.debug.bin + ls -l VGABIOS-lgpl-latest.debug.bin + +vgabios-cirrus.bin: vgabios.c vgabios.h vgafonts.h vgatables.h clext.c + $(GCC) -E -P vgabios.c $(VGABIOS_VERS) -DCIRRUS -DPCIBIOS $(VGABIOS_DATE) > _vgabios-cirrus_.c + $(BCC) -o vgabios-cirrus.s -C-c -D__i86__ -S -0 _vgabios-cirrus_.c + sed -e 's/^\.text//' -e 's/^\.data//' vgabios-cirrus.s > _vgabios-cirrus_.s + $(AS86) _vgabios-cirrus_.s -b vgabios-cirrus.bin -u -w- -g -0 -j -O -l vgabios.cirrus.txt + rm -f _vgabios-cirrus_.s _vgabios-cirrus_.c vgabios-cirrus.s + mv vgabios-cirrus.bin VGABIOS-lgpl-latest.cirrus.bin + ./biossums VGABIOS-lgpl-latest.cirrus.bin + ls -l VGABIOS-lgpl-latest.cirrus.bin + +vgabios-cirrus.debug.bin: vgabios.c vgabios.h vgafonts.h vgatables.h clext.c + $(GCC) -E -P vgabios.c $(VGABIOS_VERS) -DCIRRUS -DCIRRUS_DEBUG -DPCIBIOS $(VGABIOS_DATE) > _vgabios-cirrus-debug_.c + $(BCC) -o vgabios-cirrus-debug.s -C-c -D__i86__ -S -0 _vgabios-cirrus-debug_.c + sed -e 's/^\.text//' -e 's/^\.data//' vgabios-cirrus-debug.s > _vgabios-cirrus-debug_.s + $(AS86) _vgabios-cirrus-debug_.s -b vgabios.cirrus.debug.bin -u -w- -g -0 -j -O -l vgabios.cirrus.debug.txt + rm -f _vgabios-cirrus-debug_.s _vgabios-cirrus-debug_.c vgabios-cirrus-debug.s + mv vgabios.cirrus.debug.bin VGABIOS-lgpl-latest.cirrus.debug.bin + ./biossums VGABIOS-lgpl-latest.cirrus.debug.bin + ls -l VGABIOS-lgpl-latest.cirrus.debug.bin + +biossums: biossums.c + $(CC) -o biossums biossums.c + +vbetables-gen: vbetables-gen.c + $(CC) -o vbetables-gen vbetables-gen.c + +vbetables.h: vbetables-gen + ./vbetables-gen > $@ @@ -0,0 +1,11 @@ +Development notes +----------------- + +- need to split video init function + 1. set bios variables + 2. do the real init with io based on bios variables + +- characters format switching will set the bios + variables and call function #2 above + +- need to rework the tables as explained in Interrupt list @@ -0,0 +1,226 @@ +Plex86/Bochs VGABios +-------------------- + +The goal of this project is to have a LGPL'd Video Bios in plex86, +Bochs and qemu. +This VGA Bios is very specific to the emulated VGA card. +It is NOT meant to drive a physical vga card. + + +Cirrus SVGA extension +--------------------- + +The Cirrus SVGA extension is designed for the Cirrus emulation in Bochs and +qemu. The initial patch for the Cirrus extension has been written by Makoto +Suzuki (suzu). + + +Install +------- +To compile the VGA Bios you will need : +- gcc +- bcc +- as86 +- ld86 + +Untar the archive, and type make. You should get a "VGABIOS-lgpl-latest.bin" +file. Alternatively, you can use the binary file "VGABIOS-lgpl-latest.bin", +i have compiled for you. + +Edit your plex86/bochs conf file, and modify the load-rom command in the +VGA BIOS section, to point to the new vgabios image file. + + +Debugging +--------- +You can get a very basic debugging system: messages printed by the vgabios. +You have to register the "unmapped" device driver in plex86 or bochs, and make +sure it grabs port 0xfff0. + +Comment the #undef DEBUG at the beginning of vgabios.c. +You can then use the "printf" function in the bios. + + +Testing +------- +Look at the "testvga.c" file in the archive. This is a minimal Turbo C 2.0 +source file that calls a few int10 functions. Feel free to modify it to suit +your needs. + + +Copyright and License +--------------------- +This program has been written by Christophe Bothamy +It is protected by the GNU Lesser Public License, which you should +have received a copy of along with this package. + + +Reverse Engineering +------------------- +The VGA Bios has been written without reverse-engineering any existing Bios. + + +Acknowledgment +-------------- +The source code contains code ripped from rombios.c of plex86, written +by Kevin Lawton <kevin2001@yahoo.com> + +The source code contains fonts from fntcol16.zip (c) by Joseph Gil avalable at : +ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip +These fonts are public domain + +The source code is based on information taken from : +- Kevin Lawton's vga card emulation for bochs/plex86 +- Ralf Brown's interrupts list avalaible at + http://www.cs.cmu.edu/afs/cs/user/ralf/pub/WWW/files.html +- Finn Thogersons' VGADOC4b available at http://home.worldonline.dk/~finth/ +- Michael Abrash's Graphics Programming Black Book +- Francois Gervais' book "programmation des cartes graphiques cga-ega-vga" + edited by sybex +- DOSEMU 1.0.1 source code for several tables values and formulas + + +Feedback +-------- +Please report any bugs, comments, patches for this VGA Bios to info@vruppert.de +You can find the latest release at : http://www.nongnu.org/vgabios/ +For any information on bochs, visit the website http://bochs.sourceforge.net/ +For any information on qemu, visit the website http://fabrice.bellard.free.fr/qemu/ + + +History +------- +vgabios-0.6c : Apr 08 2009 + - Volker + . added DPMS support to cirrus vgabios (patch from Gleb Natapov) + . use VBE LFB address from PCI base address if present + . added support for a lot more non-standard VBE modes (e.g. widescreen modes) + . minor bugfixes + +vgabios-0.6b : May 30 2008 + - Volker + . added PCI data structure for the Cirrus VGABIOS images + . minor bugfixes in biossums utility, VBE support and makefile + +vgabios-0.6a : Aug 19 2006 + - Volker + . added minimal support for the video parameter table (VPT) + . Cirrus SVGA now supports the "no clear" bit in Cirrus and VESA mode + . Bochs VBE protected mode interface improved + . save/restore video state support for Bochs VBE and standard VGA added + . generate vbetables.h dynamicly + . VBE video memory increased to 8 MB (VBE dispi ID changed to B0C4) + . lots of 4bpp VBE fixes (all 4bpp VBE modes now enabled) + . VGA compatible setup for VBE modes added + +vgabios-0.5d : Dec 29 2005 + - Volker + . Bochs VBE protected mode interface added (based on a patch by malc@pulsesoft.com) + . biossums utility now supports VGABIOS sizes up to 64 kBytes + . VGA mode 0x11: all color planes must be enabled in this 2-color VGA mode + +vgabios-0.5c : Jul 07 2005 + - Volker + . BIOS configuration word usually reports initial mode 80x25 color text + . vgabios function 0x0e (write teletype): linefeed (0x0a) only increments the + cursor row value + +vgabios-0.5b : May 24 2005 + - Volker + . fixed return value for the default case in the VBE section (non-debug mode) + . removed unused stuff + +vgabios-0.5a : Mar 07 2005 + - Volker + . Cirrus SVGA extension (initial patches from Makoto Suzuki, improvements + from Fabrice Bellard) + . vgabios image size is now exactly 32k with a checksum + . a lot of vgabios and vbe functions rewritten in assembler + . dynamicly generated VBE mode info list + . write character function for CGA and LINEAR8 modes + . read/write graphics pixel for some graphics modes + . text scroll feature for some graphics modes + . VBE 8-bit DAC support + +vgabios-0.4c : Nov 06 2003 + - Christophe + . fix font problem on initial screen of NT4 Loader + +vgabios-0.4b : Nov 04 2003 + - Volker + . fix offset of character tables + . optimizations of CRT controller accesses + . VBE i/o registers changed to 0x01CE/CF + (suggestion from Daniel Gimpelevich) + . "noclear" flag stored in BIOS area + . fix character height returned by get_font_info function + +vgabios-0.4a : Aug 17 2003 + - Volker + . VBE mode search rewritten (VBE modes with LFB bit removed) + . many bugfixes and optimizations + . write character function implemented for graphics modes + . support for 15bpp, 16bpp, 24bpp and 32bpp VBE modes added + . SVGA mode 0x6A added + . VBE modes 0x102, 0x117, 0x118 and 0x142 (Bochs specific) + +vgabios-0.3b : Nov 23 2002 + - Christophe + . added lfb-mode numbers (patch from mathis) + . updated the Makefile + . removed display of copyrights. + . changed the Copyright string to "LGPL VGABios developers" + - Volker + . set the cursor shape depending on the current font height + . clear BL before calling int 0x10 function 0x1103 in vgabios_init_func + . added some text font functions + - Jeroen + . Forced to new DISPI (0xb0c1) interface (requires latest bochs vbe code) + . Added multibuffering support + . Added new DISPI interface for: virt width, height, x offset, y offset + . Added LFB modes (to be used with the vbe-lfb patch in bochs) + see VBE_HAVE_LFB in vbe.c (currently default enabled) + . updated TODO & docs for changes after bochs 1.4 + +vgabios-0.3a : Mar 10 2002 + - Christophe + . Fixed bug in function ah=13 + - Jeroen + . updated vbebios implementation to new api + . added vbe_display_api documentation + . added 640x400x8, 640x480x8, 800x600x8, 1024x768 + (>640x480 needs a special bochs patch atm) + . added 320x200x8 vbe support (uses the standard 320x200x8 vga mode to + display, this allows for testing & having something on screen as well, + at least until bochs host side display is up & running) + . adding lfbprof (vbe) testprogram (+some small fixes to it) + . merging with vbebios 0.2 + +vgabios-0.2b : Nov 19 2001 + - Christophe + . Fixed bug in function ah=13 + +vgabios-0.2a : Nov 09 2001 + - Christophe + . Included bugfix from techt@pikeonline.net about grayscale summing + . Added the "IBM" string at org 0x1e as Bart Oldeman suggested + . Fixed DS and ES that where inverted in the int10 parameters list! + . The following have been implemented : + - function ax=1a00, ax=1a01, ah=1b + - function ax=1130 + . Added debug messages for unimplemented/unknown functions + Must be compiled with DEBUG defined. The output is trapped + by the unknown-ioport driver of plex/bochs (port 0xfff0 is used) + +vgabios-0.1a : May 8 2001 + - Christophe + . First release. The work has been focused only on text mode. + . The following have been implemented : + - inits + - int 10 handler + - functions ah=00, ah=01, ah=02, ah=03, ah=05, ah=06, ah=07, ah=08 + ah=09, ah=0a, ah=0e, ah=0f, ax=1000, ax=1001, ax=1002, ax=1003 + ax=1007, ax=1008, ax=1009, ax=1010, ax=1012, ax=1013, ax=1015 + ax=1017, ax=1018, ax=1019, ax=101a, ax=101b, ah=12 bl=10, + ah=12 bl=30, ah=12 bl=31, ah=12 bl=32, ah=12 bl=33, ah=12 bl=34 + ah=13 @@ -0,0 +1,26 @@ +Short term : +------------ + +General + - Fix init mode (ah=00). Should use more BIOS variables + - Add new functionalities and modify static functionality table + - Performance : 16 bits IO + +v0.7 + - Implement the remaining functions (don't know if all are needed): + - chargen ax=1120, ax=1121, ax=1122, ax=1123, ax=1124 + - display switch interface ah=12 bl=35 + - video refresh control ah=12 bl=36 + - Graphic modes + +v1.0 + - Bugfixes + + +================================================================================================= +VBE: +---- +Long term: +- have plex86 host side display interface +- have text io functions in vbe mode + diff --git a/VGABIOS-lgpl-latest.bin b/VGABIOS-lgpl-latest.bin Binary files differnew file mode 100644 index 0000000..24d03a8 --- /dev/null +++ b/VGABIOS-lgpl-latest.bin diff --git a/VGABIOS-lgpl-latest.cirrus.bin b/VGABIOS-lgpl-latest.cirrus.bin Binary files differnew file mode 100644 index 0000000..e514fd0 --- /dev/null +++ b/VGABIOS-lgpl-latest.cirrus.bin diff --git a/VGABIOS-lgpl-latest.cirrus.debug.bin b/VGABIOS-lgpl-latest.cirrus.debug.bin Binary files differnew file mode 100644 index 0000000..760e862 --- /dev/null +++ b/VGABIOS-lgpl-latest.cirrus.debug.bin diff --git a/VGABIOS-lgpl-latest.debug.bin b/VGABIOS-lgpl-latest.debug.bin Binary files differnew file mode 100644 index 0000000..dfc968b --- /dev/null +++ b/VGABIOS-lgpl-latest.debug.bin diff --git a/biossums.c b/biossums.c new file mode 100644 index 0000000..d5816f4 --- /dev/null +++ b/biossums.c @@ -0,0 +1,282 @@ +/* biossums.c --- written by Eike W. for the Bochs BIOS */ +/* adapted for the LGPL'd VGABIOS by vruppert */ + +/* This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +typedef unsigned char byte; + +void check( int value, char* message ); + +#define MAX_BIOS_DATA 0x10000 + +long chksum_bios_get_offset( byte* data, long offset ); +byte chksum_bios_calc_value( byte* data, long offset ); +byte chksum_bios_get_value( byte* data, long offset ); +void chksum_bios_set_value( byte* data, long offset, byte value ); + +#define PMID_LEN 20 +#define PMID_CHKSUM 19 + +long chksum_pmid_get_offset( byte* data, long offset ); +byte chksum_pmid_calc_value( byte* data, long offset ); +byte chksum_pmid_get_value( byte* data, long offset ); +void chksum_pmid_set_value( byte* data, long offset, byte value ); + +#define PCIR_LEN 24 + +long chksum_pcir_get_offset( byte* data, long offset ); + + +byte bios_data[MAX_BIOS_DATA]; +long bios_len; + + +int main(int argc, char* argv[]) +{ + FILE* stream; + long offset, tmp_offset, pcir_offset; + byte bios_len_byte, cur_val = 0, new_val = 0; + int hits, modified; + + if (argc != 2) { + printf( "Error. Need a file-name as an argument.\n" ); + exit( EXIT_FAILURE ); + } + + if ((stream = fopen(argv[1], "rb")) == NULL) { + printf("Error opening %s for reading.\n", argv[1]); + exit(EXIT_FAILURE); + } + memset(bios_data, 0, MAX_BIOS_DATA); + bios_len = fread(bios_data, 1, MAX_BIOS_DATA, stream); + if (bios_len > MAX_BIOS_DATA) { + printf("Error reading max. 65536 Bytes from %s.\n", argv[1]); + fclose(stream); + exit(EXIT_FAILURE); + } + fclose(stream); + modified = 0; + if (bios_len < 0x8000) { + bios_len = 0x8000; + modified = 1; + } else if ((bios_len & 0x1FF) != 0) { + bios_len = (bios_len + 0x200) & ~0x1FF; + modified = 1; + } + bios_len_byte = (byte)(bios_len / 512); + if (bios_len_byte != bios_data[2]) { + if (modified == 0) { + bios_len += 0x200; + } + bios_data[2] = (byte)(bios_len / 512); + modified = 1; + } + + hits = 0; + offset = 0L; + while( (tmp_offset = chksum_pmid_get_offset( bios_data, offset )) != -1L ) { + offset = tmp_offset; + cur_val = chksum_pmid_get_value( bios_data, offset ); + new_val = chksum_pmid_calc_value( bios_data, offset ); + printf( "\nPMID entry at: 0x%4lX\n", offset ); + printf( "Current checksum: 0x%02X\n", cur_val ); + printf( "Calculated checksum: 0x%02X ", new_val ); + hits++; + } + if ((hits == 1) && (cur_val != new_val)) { + printf("Setting checksum."); + chksum_pmid_set_value( bios_data, offset, new_val ); + if (modified == 0) { + bios_len += 0x200; + bios_data[2]++; + } + modified = 1; + } + if (hits >= 2) { + printf( "Multiple PMID entries! No checksum set." ); + } + if (hits) { + printf("\n"); + } + + offset = 0L; + pcir_offset = chksum_pcir_get_offset( bios_data, offset ); + if (pcir_offset != -1L) { + if (bios_data[pcir_offset + 16] != bios_data[2]) { + bios_data[pcir_offset + 16] = bios_data[2]; + if (modified == 0) { + bios_len += 0x200; + bios_data[2]++; + bios_data[pcir_offset + 16]++; + } + modified = 1; + } + } + + offset = 0L; + do { + offset = chksum_bios_get_offset(bios_data, offset); + cur_val = chksum_bios_get_value(bios_data, offset); + new_val = chksum_bios_calc_value(bios_data, offset); + if ((cur_val != new_val) && (modified == 0)) { + bios_len += 0x200; + bios_data[2]++; + if (pcir_offset != -1L) { + bios_data[pcir_offset + 16]++; + } + modified = 1; + } else { + printf("\nBios checksum at: 0x%4lX\n", offset); + printf("Current checksum: 0x%02X\n", cur_val); + printf("Calculated checksum: 0x%02X ", new_val); + if (cur_val != new_val) { + printf("Setting checksum."); + chksum_bios_set_value(bios_data, offset, new_val); + cur_val = new_val; + modified = 1; + } + printf( "\n" ); + } + } while (cur_val != new_val); + + if (modified == 1) { + if ((stream = fopen( argv[1], "wb")) == NULL) { + printf("Error opening %s for writing.\n", argv[1]); + exit(EXIT_FAILURE); + } + if (fwrite(bios_data, 1, bios_len, stream) < bios_len) { + printf("Error writing %d KBytes to %s.\n", bios_len / 1024, argv[1]); + fclose(stream); + exit(EXIT_FAILURE); + } + fclose(stream); + } + + return (EXIT_SUCCESS); +} + + +void check( int okay, char* message ) { + + if( !okay ) { + printf( "\n\nError. %s.\n", message ); + exit( EXIT_FAILURE ); + } +} + + +long chksum_bios_get_offset( byte* data, long offset ) { + + return (bios_len - 1); +} + + +byte chksum_bios_calc_value( byte* data, long offset ) { + + int i; + byte sum; + + sum = 0; + for( i = 0; i < offset; i++ ) { + sum = sum + *( data + i ); + } + sum = -sum; /* iso ensures -s + s == 0 on unsigned types */ + return( sum ); +} + + +byte chksum_bios_get_value( byte* data, long offset ) { + + return( *( data + offset ) ); +} + + +void chksum_bios_set_value( byte* data, long offset, byte value ) { + + *( data + offset ) = value; +} + + +byte chksum_pmid_calc_value( byte* data, long offset ) { + + int i; + int len; + byte sum; + + len = PMID_LEN; + check((offset + len) <= (bios_len - 1), "PMID entry length out of bounds" ); + sum = 0; + for( i = 0; i < len; i++ ) { + if( i != PMID_CHKSUM ) { + sum = sum + *( data + offset + i ); + } + } + sum = -sum; + return( sum ); +} + + +long chksum_pmid_get_offset( byte* data, long offset ) { + + long result = -1L; + + while ((offset + PMID_LEN) < (bios_len - 1)) { + offset = offset + 1; + if( *( data + offset + 0 ) == 'P' && \ + *( data + offset + 1 ) == 'M' && \ + *( data + offset + 2 ) == 'I' && \ + *( data + offset + 3 ) == 'D' ) { + result = offset; + break; + } + } + return( result ); +} + + +byte chksum_pmid_get_value( byte* data, long offset ) { + + check((offset + PMID_CHKSUM) <= (bios_len - 1), "PMID checksum out of bounds" ); + return( *( data + offset + PMID_CHKSUM ) ); +} + + +void chksum_pmid_set_value( byte* data, long offset, byte value ) { + + check((offset + PMID_CHKSUM) <= (bios_len - 1), "PMID checksum out of bounds" ); + *( data + offset + PMID_CHKSUM ) = value; +} + + +long chksum_pcir_get_offset( byte* data, long offset ) { + + long result = -1L; + + while ((offset + PCIR_LEN) < (bios_len - 1)) { + offset = offset + 1; + if( *( data + offset + 0 ) == 'P' && \ + *( data + offset + 1 ) == 'C' && \ + *( data + offset + 2 ) == 'I' && \ + *( data + offset + 3 ) == 'R' ) { + result = offset; + break; + } + } + return( result ); +} @@ -0,0 +1,1652 @@ +// +// QEMU Cirrus CLGD 54xx VGABIOS Extension. +// +// Copyright (c) 2004 Makoto Suzuki (suzu) +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// + +//#define CIRRUS_VESA3_PMINFO +#ifdef VBE +#undef CIRRUS_VESA3_PMINFO +#endif + +#define PM_BIOSMEM_CURRENT_MODE 0x449 +#define PM_BIOSMEM_CRTC_ADDRESS 0x463 +#define PM_BIOSMEM_VBE_MODE 0x4BA + +typedef struct +{ + /* + 0 */ + unsigned short mode; + unsigned short width; + unsigned short height; + unsigned short depth; + /* + 8 */ + unsigned short hidden_dac; /* 0x3c6 */ + unsigned short *seq; /* 0x3c4 */ + unsigned short *graph; /* 0x3ce */ + unsigned short *crtc; /* 0x3d4 */ + /* +16 */ + unsigned char bitsperpixel; + unsigned char vesacolortype; + unsigned char vesaredmask; + unsigned char vesaredpos; + unsigned char vesagreenmask; + unsigned char vesagreenpos; + unsigned char vesabluemask; + unsigned char vesabluepos; + /* +24 */ + unsigned char vesareservedmask; + unsigned char vesareservedpos; +} cirrus_mode_t; +#define CIRRUS_MODE_SIZE 26 + + +/* For VESA BIOS 3.0 */ +#define CIRRUS_PM16INFO_SIZE 20 + +/* VGA */ +unsigned short cseq_vga[] = {0x0007,0xffff}; +unsigned short cgraph_vga[] = {0x0009,0x000a,0x000b,0xffff}; +unsigned short ccrtc_vga[] = {0x001a,0x001b,0x001d,0xffff}; + +/* extensions */ +unsigned short cgraph_svgacolor[] = { +0x0000,0x0001,0x0002,0x0003,0x0004,0x4005,0x0506,0x0f07,0xff08, +0x0009,0x000a,0x000b, +0xffff +}; +/* 640x480x8 */ +unsigned short cseq_640x480x8[] = { +0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, +0x580b,0x580c,0x580d,0x580e, +0x0412,0x0013,0x2017, +0x331b,0x331c,0x331d,0x331e, +0xffff +}; +unsigned short ccrtc_640x480x8[] = { +0x2c11, +0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, +0x4009,0x000c,0x000d, +0xea10,0xdf12,0x5013,0x4014,0xdf15,0x0b16,0xc317,0xff18, +0x001a,0x221b,0x001d, +0xffff +}; +/* 640x480x16 */ +unsigned short cseq_640x480x16[] = { +0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, +0x580b,0x580c,0x580d,0x580e, +0x0412,0x0013,0x2017, +0x331b,0x331c,0x331d,0x331e, +0xffff +}; +unsigned short ccrtc_640x480x16[] = { +0x2c11, +0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, +0x4009,0x000c,0x000d, +0xea10,0xdf12,0xa013,0x4014,0xdf15,0x0b16,0xc317,0xff18, +0x001a,0x221b,0x001d, +0xffff +}; +/* 640x480x24 */ +unsigned short cseq_640x480x24[] = { +0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507, +0x580b,0x580c,0x580d,0x580e, +0x0412,0x0013,0x2017, +0x331b,0x331c,0x331d,0x331e, +0xffff +}; +unsigned short ccrtc_640x480x24[] = { +0x2c11, +0x5f00,0x4f01,0x4f02,0x8003,0x5204,0x1e05,0x0b06,0x3e07, +0x4009,0x000c,0x000d, +0xea10,0xdf12,0x0013,0x4014,0xdf15,0x0b16,0xc317,0xff18, +0x001a,0x321b,0x001d, +0xffff +}; +/* 800x600x8 */ +unsigned short cseq_800x600x8[] = { +0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, +0x230b,0x230c,0x230d,0x230e, +0x0412,0x0013,0x2017, +0x141b,0x141c,0x141d,0x141e, +0xffff +}; +unsigned short ccrtc_800x600x8[] = { +0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, +0x6009,0x000c,0x000d, +0x7d10,0x5712,0x6413,0x4014,0x5715,0x9816,0xc317,0xff18, +0x001a,0x221b,0x001d, +0xffff +}; +/* 800x600x16 */ +unsigned short cseq_800x600x16[] = { +0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, +0x230b,0x230c,0x230d,0x230e, +0x0412,0x0013,0x2017, +0x141b,0x141c,0x141d,0x141e, +0xffff +}; +unsigned short ccrtc_800x600x16[] = { +0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, +0x6009,0x000c,0x000d, +0x7d10,0x5712,0xc813,0x4014,0x5715,0x9816,0xc317,0xff18, +0x001a,0x221b,0x001d, +0xffff +}; +/* 800x600x24 */ +unsigned short cseq_800x600x24[] = { +0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507, +0x230b,0x230c,0x230d,0x230e, +0x0412,0x0013,0x2017, +0x141b,0x141c,0x141d,0x141e, +0xffff +}; +unsigned short ccrtc_800x600x24[] = { +0x2311,0x7d00,0x6301,0x6302,0x8003,0x6b04,0x1a05,0x9806,0xf007, +0x6009,0x000c,0x000d, +0x7d10,0x5712,0x2c13,0x4014,0x5715,0x9816,0xc317,0xff18, +0x001a,0x321b,0x001d, +0xffff +}; +/* 1024x768x8 */ +unsigned short cseq_1024x768x8[] = { +0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, +0x760b,0x760c,0x760d,0x760e, +0x0412,0x0013,0x2017, +0x341b,0x341c,0x341d,0x341e, +0xffff +}; +unsigned short ccrtc_1024x768x8[] = { +0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, +0x6009,0x000c,0x000d, +0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18, +0x001a,0x221b,0x001d, +0xffff +}; +/* 1024x768x16 */ +unsigned short cseq_1024x768x16[] = { +0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, +0x760b,0x760c,0x760d,0x760e, +0x0412,0x0013,0x2017, +0x341b,0x341c,0x341d,0x341e, +0xffff +}; +unsigned short ccrtc_1024x768x16[] = { +0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, +0x6009,0x000c,0x000d, +0x0310,0xff12,0x0013,0x4014,0xff15,0x2416,0xc317,0xff18, +0x001a,0x321b,0x001d, +0xffff +}; +/* 1024x768x24 */ +unsigned short cseq_1024x768x24[] = { +0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1507, +0x760b,0x760c,0x760d,0x760e, +0x0412,0x0013,0x2017, +0x341b,0x341c,0x341d,0x341e, +0xffff +}; +unsigned short ccrtc_1024x768x24[] = { +0x2911,0xa300,0x7f01,0x7f02,0x8603,0x8304,0x9405,0x2406,0xf507, +0x6009,0x000c,0x000d, +0x0310,0xff12,0x8013,0x4014,0xff15,0x2416,0xc317,0xff18, +0x001a,0x321b,0x001d, +0xffff +}; +/* 1280x1024x8 */ +unsigned short cseq_1280x1024x8[] = { +0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, +0x760b,0x760c,0x760d,0x760e, +0x0412,0x0013,0x2017, +0x341b,0x341c,0x341d,0x341e, +0xffff +}; +unsigned short ccrtc_1280x1024x8[] = { +0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707, +0x6009,0x000c,0x000d, +0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18, +0x001a,0x221b,0x001d, +0xffff +}; +/* 1280x1024x16 */ +unsigned short cseq_1280x1024x16[] = { +0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1707, +0x760b,0x760c,0x760d,0x760e, +0x0412,0x0013,0x2017, +0x341b,0x341c,0x341d,0x341e, +0xffff +}; +unsigned short ccrtc_1280x1024x16[] = { +0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707, +0x6009,0x000c,0x000d, +0x0310,0xff12,0x4013,0x4014,0xff15,0x2416,0xc317,0xff18, +0x001a,0x321b,0x001d, +0xffff +}; + +/* 1600x1200x8 */ +unsigned short cseq_1600x1200x8[] = { +0x0300,0x2101,0x0f02,0x0003,0x0e04,0x1107, +0x760b,0x760c,0x760d,0x760e, +0x0412,0x0013,0x2017, +0x341b,0x341c,0x341d,0x341e, +0xffff +}; +unsigned short ccrtc_1600x1200x8[] = { +0x2911,0xc300,0x9f01,0x9f02,0x8603,0x8304,0x9405,0x2406,0xf707, +0x6009,0x000c,0x000d, +0x0310,0xff12,0xa013,0x4014,0xff15,0x2416,0xc317,0xff18, +0x001a,0x221b,0x001d, +0xffff +}; + +cirrus_mode_t cirrus_modes[] = +{ + {0x5f,640,480,8,0x00, + cseq_640x480x8,cgraph_svgacolor,ccrtc_640x480x8,8, + 4,0,0,0,0,0,0,0,0}, + {0x64,640,480,16,0xe1, + cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, + 6,5,11,6,5,5,0,0,0}, + {0x66,640,480,15,0xf0, + cseq_640x480x16,cgraph_svgacolor,ccrtc_640x480x16,16, + 6,5,10,5,5,5,0,1,15}, + {0x71,640,480,24,0xe5, + cseq_640x480x24,cgraph_svgacolor,ccrtc_640x480x24,24, + 6,8,16,8,8,8,0,0,0}, + + {0x5c,800,600,8,0x00, + cseq_800x600x8,cgraph_svgacolor,ccrtc_800x600x8,8, + 4,0,0,0,0,0,0,0,0}, + {0x65,800,600,16,0xe1, + cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, + 6,5,11,6,5,5,0,0,0}, + {0x67,800,600,15,0xf0, + cseq_800x600x16,cgraph_svgacolor,ccrtc_800x600x16,16, + 6,5,10,5,5,5,0,1,15}, + + {0x60,1024,768,8,0x00, + cseq_1024x768x8,cgraph_svgacolor,ccrtc_1024x768x8,8, + 4,0,0,0,0,0,0,0,0}, + {0x74,1024,768,16,0xe1, + cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, + 6,5,11,6,5,5,0,0,0}, + {0x68,1024,768,15,0xf0, + cseq_1024x768x16,cgraph_svgacolor,ccrtc_1024x768x16,16, + 6,5,10,5,5,5,0,1,15}, + + {0x78,800,600,24,0xe5, + cseq_800x600x24,cgraph_svgacolor,ccrtc_800x600x24,24, + 6,8,16,8,8,8,0,0,0}, + {0x79,1024,768,24,0xe5, + cseq_1024x768x24,cgraph_svgacolor,ccrtc_1024x768x24,24, + 6,8,16,8,8,8,0,0,0}, + + {0x6d,1280,1024,8,0x00, + cseq_1280x1024x8,cgraph_svgacolor,ccrtc_1280x1024x8,8, + 4,0,0,0,0,0,0,0,0}, + {0x69,1280,1024,15,0xf0, + cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, + 6,5,10,5,5,5,0,1,15}, + {0x75,1280,1024,16,0xe1, + cseq_1280x1024x16,cgraph_svgacolor,ccrtc_1280x1024x16,16, + 6,5,11,6,5,5,0,0,0}, + + {0x7b,1600,1200,8,0x00, + cseq_1600x1200x8,cgraph_svgacolor,ccrtc_1600x1200x8,8, + 4,0,0,0,0,0,0,0,0}, + + {0xfe,0,0,0,0,cseq_vga,cgraph_vga,ccrtc_vga,0, + 0xff,0,0,0,0,0,0,0,0}, + {0xff,0,0,0,0,0,0,0,0, + 0xff,0,0,0,0,0,0,0,0}, +}; + +unsigned char cirrus_id_table[] = { + // 5430 + 0xA0, 0x32, + // 5446 + 0xB8, 0x39, + + 0xff, 0xff +}; + + +unsigned short cirrus_vesa_modelist[] = { +// 640x480x8 + 0x101, 0x5f, +// 640x480x15 + 0x110, 0x66, +// 640x480x16 + 0x111, 0x64, +// 640x480x24 + 0x112, 0x71, +// 800x600x8 + 0x103, 0x5c, +// 800x600x15 + 0x113, 0x67, +// 800x600x16 + 0x114, 0x65, +// 800x600x24 + 0x115, 0x78, +// 1024x768x8 + 0x105, 0x60, +// 1024x768x15 + 0x116, 0x68, +// 1024x768x16 + 0x117, 0x74, +// 1024x768x24 + 0x118, 0x79, +// 1280x1024x8 + 0x107, 0x6d, +// 1280x1024x15 + 0x119, 0x69, +// 1280x1024x16 + 0x11a, 0x75, +// invalid + 0xffff,0xffff +}; + + +ASM_START + +cirrus_installed: +.ascii "cirrus-compatible VGA is detected" +.byte 0x0d,0x0a +.byte 0x0d,0x0a,0x00 + +cirrus_not_installed: +.ascii "cirrus-compatible VGA is not detected" +.byte 0x0d,0x0a +.byte 0x0d,0x0a,0x00 + +cirrus_vesa_vendorname: +cirrus_vesa_productname: +cirrus_vesa_oemname: +.ascii "VGABIOS Cirrus extension" +.byte 0 +cirrus_vesa_productrevision: +.ascii "1.0" +.byte 0 + +cirrus_init: + call cirrus_check + jnz no_cirrus + SET_INT_VECTOR(0x10, #0xC000, #cirrus_int10_handler) + mov al, #0x0f ; memory setup + mov dx, #0x3C4 + out dx, al + inc dx + in al, dx + and al, #0x18 + mov ah, al + mov al, #0x0a + dec dx + out dx, ax + mov ax, #0x0007 ; set vga mode + out dx, ax + mov ax, #0x0431 ; reset bitblt + mov dx, #0x3CE + out dx, ax + mov ax, #0x0031 + out dx, ax +no_cirrus: + ret + +cirrus_display_info: + push ds + push si + push cs + pop ds + call cirrus_check + mov si, #cirrus_not_installed + jnz cirrus_msgnotinstalled + mov si, #cirrus_installed + +cirrus_msgnotinstalled: + call _display_string + pop si + pop ds + ret + +cirrus_check: + push ax + push dx + mov ax, #0x9206 + mov dx, #0x3C4 + out dx, ax + inc dx + in al, dx + cmp al, #0x12 + pop dx + pop ax + ret + + +cirrus_int10_handler: + pushf + push bp + cmp ah, #0x00 ;; set video mode + jz cirrus_set_video_mode + cmp ah, #0x12 ;; cirrus extension + jz cirrus_extbios + cmp ah, #0x4F ;; VESA extension + jz cirrus_vesa + +cirrus_unhandled: + pop bp + popf + jmp vgabios_int10_handler + +cirrus_return: +#ifdef CIRRUS_DEBUG + call cirrus_debug_dump +#endif + pop bp + popf + iret + +cirrus_set_video_mode: +#ifdef CIRRUS_DEBUG + call cirrus_debug_dump +#endif + push si + push ax + push bx + push ds +#ifdef CIRRUS_VESA3_PMINFO + db 0x2e ;; cs: + mov si, [cirrus_vesa_sel0000_data] +#else + xor si, si +#endif + mov ds, si + xor bx, bx + mov [PM_BIOSMEM_VBE_MODE], bx + pop ds + pop bx + call cirrus_get_modeentry + jnc cirrus_set_video_mode_extended + mov al, #0xfe + call cirrus_get_modeentry_nomask + call cirrus_switch_mode + pop ax + pop si + jmp cirrus_unhandled + +cirrus_extbios: +#ifdef CIRRUS_DEBUG + call cirrus_debug_dump +#endif + cmp bl, #0x80 + jb cirrus_unhandled + cmp bl, #0xAF + ja cirrus_unhandled + push bx + and bx, #0x7F + shl bx, 1 + db 0x2e ;; cs: + mov bp, cirrus_extbios_handlers[bx] + pop bx + push #cirrus_return + push bp + ret + +cirrus_vesa: +#ifdef CIRRUS_DEBUG + call cirrus_debug_dump +#endif + cmp al, #0x10 + ja cirrus_vesa_not_handled + push bx + xor bx, bx + mov bl, al + shl bx, 1 + db 0x2e ;; cs: + mov bp, cirrus_vesa_handlers[bx] + pop bx + push #cirrus_return + push bp + ret + +cirrus_vesa_not_handled: + mov ax, #0x014F ;; not implemented + jmp cirrus_return + +#ifdef CIRRUS_DEBUG +cirrus_debug_dump: + push es + push ds + pusha + push cs + pop ds + call _cirrus_debugmsg + popa + pop ds + pop es + ret +#endif + +cirrus_set_video_mode_extended: + call cirrus_switch_mode + pop ax ;; mode + test al, #0x80 + jnz cirrus_set_video_mode_extended_1 + push ax + mov ax, #0xffff ; set to 0xff to keep win 2K happy + call cirrus_clear_vram + pop ax +cirrus_set_video_mode_extended_1: + and al, #0x7f + + push ds +#ifdef CIRRUS_VESA3_PMINFO + db 0x2e ;; cs: + mov si, [cirrus_vesa_sel0000_data] +#else + xor si, si +#endif + mov ds, si + mov [PM_BIOSMEM_CURRENT_MODE], al + pop ds + + mov al, #0x20 + + pop si + jmp cirrus_return + +cirrus_vesa_pmbios_init: + retf +cirrus_vesa_pmbios_entry: + pushf + push bp + cmp ah, #0x4F + jnz cirrus_vesa_pmbios_unimplemented + cmp al, #0x0F + ja cirrus_vesa_pmbios_unimplemented + push bx + xor bx, bx + mov bl, al + shl bx, 1 + db 0x2e ;; cs: + mov bp, cirrus_vesa_handlers[bx] + pop bx + push #cirrus_vesa_pmbios_return + push bp + ret +cirrus_vesa_pmbios_unimplemented: + mov ax, #0x014F +cirrus_vesa_pmbios_return: + pop bp + popf + retf + +; in si:mode table +cirrus_switch_mode: + push ds + push bx + push dx + push cs + pop ds + + mov bx, [si+10] ;; seq + mov dx, #0x3c4 + mov ax, #0x1206 + out dx, ax ;; Unlock cirrus special + call cirrus_switch_mode_setregs + + mov bx, [si+12] ;; graph + mov dx, #0x3ce + call cirrus_switch_mode_setregs + + mov bx, [si+14] ;; crtc + call cirrus_get_crtc + call cirrus_switch_mode_setregs + + mov dx, #0x3c6 + mov al, #0x00 + out dx, al + in al, dx + in al, dx + in al, dx + in al, dx + mov al, [si+8] ;; hidden dac + out dx, al + mov al, #0xff + out dx, al + + mov al, #0x00 + mov bl, [si+17] ;; memory model + or bl, bl + jz is_text_mode + mov al, #0x01 + cmp bl, #0x03 + jnz is_text_mode + or al, #0x40 +is_text_mode: + mov bl, #0x10 + call biosfn_get_single_palette_reg + and bh, #0xfe + or bh, al + call biosfn_set_single_palette_reg + + mov al, [si+6] ;; bpp + cmp al, #0x08 + jnz no_8bpp_mode + mov al, #0x03 + xor ah,ah + push ax + call _load_dac_palette + inc sp + inc sp +no_8bpp_mode: + + pop dx + pop bx + pop ds + ret + +cirrus_enable_16k_granularity: + push ax + push dx + mov dx, #0x3ce + mov al, #0x0b + out dx, al + inc dx + in al, dx + or al, #0x20 ;; enable 16k + out dx, al + pop dx + pop ax + ret + +cirrus_switch_mode_setregs: +csms_1: + mov ax, [bx] + cmp ax, #0xffff + jz csms_2 + out dx, ax + add bx, #0x2 + jmp csms_1 +csms_2: + ret + +cirrus_extbios_80h: + push dx + call cirrus_get_crtc + mov al, #0x27 + out dx, al + inc dx + in al, dx + mov bx, #_cirrus_id_table +c80h_1: + db 0x2e ;; cs: + mov ah, [bx] + cmp ah, al + jz c80h_2 + cmp ah, #0xff + jz c80h_2 + inc bx + inc bx + jmp c80h_1 +c80h_2: + db 0x2e ;; cs: + mov al, 0x1[bx] + pop dx + mov ah, #0x00 + xor bx, bx + ret + +cirrus_extbios_81h: + mov ax, #0x100 ;; XXX + ret +cirrus_extbios_82h: + push dx + call cirrus_get_crtc + xor ax, ax + mov al, #0x27 + out dx, al + inc dx + in al, dx + and al, #0x03 + mov ah, #0xAF + pop dx + ret + +cirrus_extbios_85h: + push cx + push dx + mov dx, #0x3C4 + mov al, #0x0f ;; get DRAM band width + out dx, al + inc dx + in al, dx + ;; al = 4 << bandwidth + mov cl, al + shr cl, #0x03 + and cl, #0x03 + cmp cl, #0x03 + je c85h2 + mov al, #0x04 + shl al, cl + jmp c85h3 +c85h2: +;; 4MB or 2MB + and al, #0x80 + mov al, #0x20 ;; 2 MB + je c85h3 + mov al, #0x40 ;; 4 MB +c85h3: + pop dx + pop cx + ret + +cirrus_extbios_9Ah: + mov ax, #0x4060 + mov cx, #0x1132 + ret + +cirrus_extbios_A0h: + call cirrus_get_modeentry + mov ah, #0x01 + sbb ah, #0x00 + mov bx, cirrus_extbios_A0h_callback + mov si, #0xffff + mov di, bx + mov ds, bx + mov es, bx + ret + +cirrus_extbios_A0h_callback: + ;; fatal: not implemented yet + cli + hlt + retf + +cirrus_extbios_A1h: + mov bx, #0x0E00 ;; IBM 8512/8513, color + ret + +cirrus_extbios_A2h: + mov al, #0x07 ;; HSync 31.5 - 64.0 kHz + ret + +cirrus_extbios_AEh: + mov al, #0x01 ;; High Refresh 75Hz + ret + +cirrus_extbios_unimplemented: + ret + +cirrus_vesa_00h: + push ds + push si + mov bp, di + push es + pop ds + cld + mov ax, [di] + cmp ax, #0x4256 ;; VB + jnz cv00_1 + mov ax, [di+2] + cmp ax, #0x3245 ;; E2 + jnz cv00_1 + ;; VBE2 + lea di, 0x14[bp] + mov ax, #0x0100 ;; soft ver. + stosw + mov ax, # cirrus_vesa_vendorname + stosw + mov ax, cs + stosw + mov ax, # cirrus_vesa_productname + stosw + mov ax, cs + stosw + mov ax, # cirrus_vesa_productrevision + stosw + mov ax, cs + stosw +cv00_1: + mov di, bp + mov ax, #0x4556 ;; VE + stosw + mov ax, #0x4153 ;; SA + stosw + mov ax, #0x0200 ;; v2.00 + stosw + mov ax, # cirrus_vesa_oemname + stosw + mov ax, cs + stosw + xor ax, ax ;; caps + stosw + stosw + lea ax, 0x40[bp] + stosw + mov ax, es + stosw + call cirrus_extbios_85h ;; vram in 64k + mov ah, #0x00 + stosw + + push cs + pop ds + lea di, 0x40[bp] + mov si, #_cirrus_vesa_modelist +cv00_2: + lodsw + stosw + add si, #2 + cmp ax, #0xffff + jnz cv00_2 + + mov ax, #0x004F + mov di, bp + pop si + pop ds + ret + +cirrus_vesa_01h: + mov ax, cx + and ax, #0x3fff + call cirrus_vesamode_to_mode + cmp ax, #0xffff + jnz cirrus_vesa_01h_1 + jmp cirrus_vesa_unimplemented +cirrus_vesa_01h_1: + push ds + push si + push cx + push dx + push bx + mov bp, di + cld + push cs + pop ds + call cirrus_get_modeentry_nomask + + push di + xor ax, ax + mov cx, #0x80 + rep + stosw ;; clear buffer + pop di + + mov ax, #0x003b ;; mode + stosw + mov ax, #0x0007 ;; attr + stosw + mov ax, #0x0010 ;; granularity =16K + stosw + mov ax, #0x0040 ;; size =64K + stosw + mov ax, #0xA000 ;; segment A + stosw + xor ax, ax ;; no segment B + stosw + mov ax, #cirrus_vesa_05h_farentry + stosw + mov ax, cs + stosw + call cirrus_get_line_offset_entry + stosw ;; bytes per scan line + mov ax, [si+2] ;; width + stosw + mov ax, [si+4] ;; height + stosw + mov ax, #0x08 + stosb + mov ax, #0x10 + stosb + mov al, #1 ;; count of planes + stosb + mov al, [si+6] ;; bpp + stosb + mov al, #0x1 ;; XXX number of banks + stosb + mov al, [si+17] + stosb ;; memory model + mov al, #0x0 ;; XXX size of bank in K + stosb + call cirrus_get_line_offset_entry + mov bx, [si+4] + mul bx ;; dx:ax=vramdisp + or ax, ax + jz cirrus_vesa_01h_3 + inc dx +cirrus_vesa_01h_3: + call cirrus_extbios_85h ;; al=vram in 64k + mov ah, #0x00 + mov cx, dx + xor dx, dx + div cx + dec ax + stosb ;; number of image pages = vramtotal/vramdisp-1 + mov al, #0x00 + stosb + + ;; v1.2+ stuffs + push si + add si, #18 + movsw + movsw + movsw + movsw + pop si + + mov ah, [si+16] + mov al, #0x0 + sub ah, #9 + rcl al, #1 ; bit 0=palette flag + stosb ;; direct screen mode info + + ;; v2.0+ stuffs + ;; 32-bit LFB address + xor ax, ax + stosw + mov ax, #0x1013 ;; vendor Cirrus + call _pci_get_lfb_addr + stosw + or ax, ax + jz cirrus_vesa_01h_4 + push di + mov di, bp + db 0x26 ;; es: + mov ax, [di] + or ax, #0x0080 ;; mode bit 7:LFB + stosw + pop di +cirrus_vesa_01h_4: + + xor ax, ax + stosw ; reserved + stosw ; reserved + stosw ; reserved + + mov ax, #0x004F + mov di, bp + pop bx + pop dx + pop cx + pop si + pop ds + + test cx, #0x4000 ;; LFB flag + jz cirrus_vesa_01h_5 + push cx + db 0x26 ;; es: + mov cx, [di] + cmp cx, #0x0080 ;; is LFB supported? + jnz cirrus_vesa_01h_6 + mov ax, #0x014F ;; error - no LFB +cirrus_vesa_01h_6: + pop cx +cirrus_vesa_01h_5: + ret + +cirrus_vesa_02h: + ;; XXX support CRTC registers + test bx, #0x3e00 + jnz cirrus_vesa_02h_2 ;; unknown flags + mov ax, bx + and ax, #0x1ff ;; bit 8-0 mode + cmp ax, #0x100 ;; legacy VGA mode + jb cirrus_vesa_02h_legacy + call cirrus_vesamode_to_mode + cmp ax, #0xffff + jnz cirrus_vesa_02h_1 +cirrus_vesa_02h_2: + jmp cirrus_vesa_unimplemented +cirrus_vesa_02h_legacy: +#ifdef CIRRUS_VESA3_PMINFO + db 0x2e ;; cs: + cmp byte ptr [cirrus_vesa_is_protected_mode], #0 + jnz cirrus_vesa_02h_2 +#endif // CIRRUS_VESA3_PMINFO + int #0x10 + mov ax, #0x004F + ret +cirrus_vesa_02h_1: + push si + push ax + call cirrus_get_modeentry_nomask + call cirrus_switch_mode + test bx, #0x4000 ;; LFB + jnz cirrus_vesa_02h_3 + call cirrus_enable_16k_granularity +cirrus_vesa_02h_3: + test bx, #0x8000 ;; no clear + jnz cirrus_vesa_02h_4 + push ax + xor ax,ax + call cirrus_clear_vram + pop ax +cirrus_vesa_02h_4: + pop ax + push ds +#ifdef CIRRUS_VESA3_PMINFO + db 0x2e ;; cs: + mov si, [cirrus_vesa_sel0000_data] +#else + xor si, si +#endif + mov ds, si + mov [PM_BIOSMEM_CURRENT_MODE], al + mov [PM_BIOSMEM_VBE_MODE], bx + pop ds + pop si + mov ax, #0x004F + ret + +cirrus_vesa_03h: + push ds +#ifdef CIRRUS_VESA3_PMINFO + db 0x2e ;; cs: + mov ax, [cirrus_vesa_sel0000_data] +#else + xor ax, ax +#endif + mov ds, ax + mov bx, # PM_BIOSMEM_VBE_MODE + mov ax, [bx] + mov bx, ax + test bx, bx + jnz cirrus_vesa_03h_1 + mov bx, # PM_BIOSMEM_CURRENT_MODE + mov al, [bx] + mov bl, al + xor bh, bh +cirrus_vesa_03h_1: + mov ax, #0x004f + pop ds + ret + +cirrus_vesa_05h_farentry: + call cirrus_vesa_05h + retf + +cirrus_vesa_05h: + cmp bl, #0x01 + ja cirrus_vesa_05h_1 + cmp bh, #0x00 + jz cirrus_vesa_05h_setmempage + cmp bh, #0x01 + jz cirrus_vesa_05h_getmempage +cirrus_vesa_05h_1: + jmp cirrus_vesa_unimplemented +cirrus_vesa_05h_setmempage: + or dh, dh ; address must be < 0x100 + jnz cirrus_vesa_05h_1 + push dx + mov al, bl ;; bl=bank number + add al, #0x09 + mov ah, dl ;; dx=window address in granularity + mov dx, #0x3ce + out dx, ax + pop dx + mov ax, #0x004F + ret +cirrus_vesa_05h_getmempage: + mov al, bl ;; bl=bank number + add al, #0x09 + mov dx, #0x3ce + out dx, al + inc dx + in al, dx + xor dx, dx + mov dl, al ;; dx=window address in granularity + mov ax, #0x004F + ret + +cirrus_vesa_06h: + mov ax, cx + cmp bl, #0x01 + je cirrus_vesa_06h_3 + cmp bl, #0x02 + je cirrus_vesa_06h_2 + jb cirrus_vesa_06h_1 + mov ax, #0x0100 + ret +cirrus_vesa_06h_1: + call cirrus_get_bpp_bytes + mov bl, al + xor bh, bh + mov ax, cx + mul bx +cirrus_vesa_06h_2: + call cirrus_set_line_offset +cirrus_vesa_06h_3: + call cirrus_get_bpp_bytes + mov bl, al + xor bh, bh + xor dx, dx + call cirrus_get_line_offset + push ax + div bx + mov cx, ax + pop bx + call cirrus_extbios_85h ;; al=vram in 64k + xor dx, dx + mov dl, al + xor ax, ax + div bx + mov dx, ax + mov ax, #0x004f + ret + +cirrus_vesa_07h: + cmp bl, #0x80 + je cirrus_vesa_07h_1 + cmp bl, #0x01 + je cirrus_vesa_07h_2 + jb cirrus_vesa_07h_1 + mov ax, #0x0100 + ret +cirrus_vesa_07h_1: + push dx + call cirrus_get_bpp_bytes + mov bl, al + xor bh, bh + mov ax, cx + mul bx + pop bx + push ax + call cirrus_get_line_offset + mul bx + pop bx + add ax, bx + jnc cirrus_vesa_07h_3 + inc dx +cirrus_vesa_07h_3: + push dx + and dx, #0x0003 + mov bx, #0x04 + div bx + pop dx + shr dx, #2 + call cirrus_set_start_addr + mov ax, #0x004f + ret +cirrus_vesa_07h_2: + call cirrus_get_start_addr + shl dx, #2 + push dx + mov bx, #0x04 + mul bx + pop bx + or dx, bx + push ax + call cirrus_get_line_offset + mov bx, ax + pop ax + div bx + push ax + push dx + call cirrus_get_bpp_bytes + mov bl, al + xor bh, bh + pop ax + xor dx, dx + div bx + mov cx, ax + pop dx + mov ax, #0x004f + ret + +cirrus_vesa_10h: + cmp bl, #0x00 + jne cirrus_vesa_10h_01 + mov bx, #0x0f30 + mov ax, #0x004f + ret +cirrus_vesa_10h_01: + cmp bl, #0x01 + jne cirrus_vesa_10h_02 + push dx + push ds + mov dx, #0x40 + mov ds, dx + mov [0xb9], bh + pop ds + pop dx + mov ax, #0x004f + ret +cirrus_vesa_10h_02: + cmp bl, #0x02 + jne cirrus_vesa_unimplemented + push dx + push ds + mov dx, #0x40 + mov ds, dx + mov bh, [0xb9] + pop ds + pop dx + mov ax, #0x004f + ret + +cirrus_vesa_unimplemented: + mov ax, #0x014F ;; not implemented + ret + + +;; in ax:vesamode, out ax:cirrusmode +cirrus_vesamode_to_mode: + push ds + push cx + push si + push cs + pop ds + mov cx, #0xffff + mov si, #_cirrus_vesa_modelist +cvtm_1: + cmp [si],ax + jz cvtm_2 + cmp [si],cx + jz cvtm_2 + add si, #4 + jmp cvtm_1 +cvtm_2: + mov ax,[si+2] + pop si + pop cx + pop ds + ret + + ; cirrus_get_crtc + ;; NOTE - may be called in protected mode +cirrus_get_crtc: + push ds + push ax + mov dx, #0x3cc + in al, dx + and al, #0x01 + shl al, #5 + mov dx, #0x3b4 + add dl, al + pop ax + pop ds + ret + +;; in - al:mode, out - cflag:result, si:table, ax:destroyed +cirrus_get_modeentry: + and al, #0x7f +cirrus_get_modeentry_nomask: + mov si, #_cirrus_modes +cgm_1: + db 0x2e ;; cs: + mov ah, [si] + cmp al, ah + jz cgm_2 + cmp ah, #0xff + jz cgm_4 + add si, # CIRRUS_MODE_SIZE + jmp cgm_1 +cgm_4: + xor si, si + stc ;; video mode is not supported + jmp cgm_3 +cgm_2: + clc ;; video mode is supported +cgm_3: + ret + +;; out - al:bytes per pixel +cirrus_get_bpp_bytes: + push dx + mov dx, #0x03c4 + mov al, #0x07 + out dx, al + inc dx + in al, dx + and al, #0x0e + cmp al, #0x06 + jne cirrus_get_bpp_bytes_1 + and al, #0x02 +cirrus_get_bpp_bytes_1: + shr al, #1 + cmp al, #0x04 + je cirrus_get_bpp_bytes_2 + inc al +cirrus_get_bpp_bytes_2: + pop dx + ret + +;; in - ax: new line offset +cirrus_set_line_offset: + shr ax, #3 + push ax + call cirrus_get_crtc + mov al, #0x13 + out dx, al + inc dx + pop ax + out dx, al + dec dx + mov al, #0x1b + out dx, al + inc dx + shl ah, #4 + in al, dx + and al, #ef + or al, ah + out dx, al + ret + +;; out - ax: active line offset +cirrus_get_line_offset: + push dx + push bx + call cirrus_get_crtc + mov al, #0x13 + out dx, al + inc dx + in al, dx + mov bl, al + dec dx + mov al, #0x1b + out dx, al + inc dx + in al, dx + mov ah, al + shr ah, #4 + and ah, #0x01 + mov al, bl + shl ax, #3 + pop bx + pop dx + ret + +;; in - si: table +;; out - ax: line offset for mode +cirrus_get_line_offset_entry: + push bx + mov bx, [si+14] ;; crtc table + push bx +offset_loop1: + mov ax, [bx] + cmp al, #0x13 + je offset_found1 + inc bx + inc bx + jnz offset_loop1 +offset_found1: + xor al, al + shr ax, #5 + pop bx + push ax +offset_loop2: + mov ax, [bx] + cmp al, #0x1b + je offset_found2 + inc bx + inc bx + jnz offset_loop2 +offset_found2: + pop bx + and ax, #0x1000 + shr ax, #1 + or ax, bx + pop bx + ret + +;; in - new address in DX:AX +cirrus_set_start_addr: + push bx + push dx + push ax + call cirrus_get_crtc + mov al, #0x0d + out dx, al + inc dx + pop ax + out dx, al + dec dx + mov al, #0x0c + out dx, al + inc dx + mov al, ah + out dx, al + dec dx + mov al, #0x1d + out dx, al + inc dx + in al, dx + and al, #0x7f + pop bx + mov ah, bl + shl bl, #4 + and bl, #0x80 + or al, bl + out dx, al + dec dx + mov bl, ah + and ah, #0x01 + shl bl, #1 + and bl, #0x0c + or ah, bl + mov al, #0x1b + out dx, al + inc dx + in al, dx + and al, #0xf2 + or al, ah + out dx, al + pop bx + ret + +;; out - current address in DX:AX +cirrus_get_start_addr: + push bx + call cirrus_get_crtc + mov al, #0x0c + out dx, al + inc dx + in al, dx + mov ah, al + dec dx + mov al, #0x0d + out dx, al + inc dx + in al, dx + push ax + dec dx + mov al, #0x1b + out dx, al + inc dx + in al, dx + dec dx + mov bl, al + and al, #0x01 + and bl, #0x0c + shr bl, #1 + or bl, al + mov al, #0x1d + out dx, al + inc dx + in al, dx + and al, #0x80 + shr al, #4 + or bl, al + mov dl, bl + xor dh, dh + pop ax + pop bx + ret + +cirrus_clear_vram: + pusha + push es + mov si, ax + + call cirrus_enable_16k_granularity + call cirrus_extbios_85h + shl al, #2 + mov bl, al + xor ah,ah +cirrus_clear_vram_1: + mov al, #0x09 + mov dx, #0x3ce + out dx, ax + push ax + mov cx, #0xa000 + mov es, cx + xor di, di + mov ax, si + mov cx, #8192 + cld + rep + stosw + pop ax + inc ah + cmp ah, bl + jne cirrus_clear_vram_1 + + xor ah,ah + mov dx, #0x3ce + out dx, ax + + pop es + popa + ret + +cirrus_extbios_handlers: + ;; 80h + dw cirrus_extbios_80h + dw cirrus_extbios_81h + dw cirrus_extbios_82h + dw cirrus_extbios_unimplemented + ;; 84h + dw cirrus_extbios_unimplemented + dw cirrus_extbios_85h + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + ;; 88h + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + ;; 8Ch + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + ;; 90h + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + ;; 94h + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + ;; 98h + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + dw cirrus_extbios_9Ah + dw cirrus_extbios_unimplemented + ;; 9Ch + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + ;; A0h + dw cirrus_extbios_A0h + dw cirrus_extbios_A1h + dw cirrus_extbios_A2h + dw cirrus_extbios_unimplemented + ;; A4h + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + ;; A8h + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + ;; ACh + dw cirrus_extbios_unimplemented + dw cirrus_extbios_unimplemented + dw cirrus_extbios_AEh + dw cirrus_extbios_unimplemented + +cirrus_vesa_handlers: + ;; 00h + dw cirrus_vesa_00h + dw cirrus_vesa_01h + dw cirrus_vesa_02h + dw cirrus_vesa_03h + ;; 04h + dw cirrus_vesa_unimplemented + dw cirrus_vesa_05h + dw cirrus_vesa_06h + dw cirrus_vesa_07h + ;; 08h + dw cirrus_vesa_unimplemented + dw cirrus_vesa_unimplemented + dw cirrus_vesa_unimplemented + dw cirrus_vesa_unimplemented + ;; 0Ch + dw cirrus_vesa_unimplemented + dw cirrus_vesa_unimplemented + dw cirrus_vesa_unimplemented + dw cirrus_vesa_unimplemented + ;; 10h + dw cirrus_vesa_10h + + +ASM_END + +#ifdef CIRRUS_VESA3_PMINFO +ASM_START +cirrus_vesa_pminfo: + /* + 0 */ + .byte 0x50,0x4d,0x49,0x44 ;; signature[4] + /* + 4 */ + dw cirrus_vesa_pmbios_entry ;; entry_bios + dw cirrus_vesa_pmbios_init ;; entry_init + /* + 8 */ +cirrus_vesa_sel0000_data: + dw 0x0000 ;; sel_00000 +cirrus_vesa_selA000_data: + dw 0xA000 ;; sel_A0000 + /* +12 */ +cirrus_vesa_selB000_data: + dw 0xB000 ;; sel_B0000 +cirrus_vesa_selB800_data: + dw 0xB800 ;; sel_B8000 + /* +16 */ +cirrus_vesa_selC000_data: + dw 0xC000 ;; sel_C0000 +cirrus_vesa_is_protected_mode: + ;; protected mode flag and checksum + dw (~((0xf2 + (cirrus_vesa_pmbios_entry >> 8) + (cirrus_vesa_pmbios_entry) \ + + (cirrus_vesa_pmbios_init >> 8) + (cirrus_vesa_pmbios_init)) & 0xff) << 8) + 0x01 +ASM_END +#endif // CIRRUS_VESA3_PMINFO + + +#ifdef CIRRUS_DEBUG +static void cirrus_debugmsg(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS) + Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS; +{ + if((GET_AH()!=0x0E)&&(GET_AH()!=0x02)&&(GET_AH()!=0x09)&&(AX!=0x4F05)) + printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX,CX,DX); +} +#endif diff --git a/dataseghack b/dataseghack new file mode 100755 index 0000000..02a2d4c --- /dev/null +++ b/dataseghack @@ -0,0 +1,23 @@ +#!/bin/bash + +awk \ + 'BEGIN { }\ + /^\.text/,/DATA_SEG_DEFS_HERE/ { print }\ + END { }'\ + $1 > temp.awk.1 + +awk \ + 'BEGIN { i = 0; last = "hello" }\ + /BLOCK_STRINGS_BEGIN/,/^\.bss/ { if ( i > 1 ) { print last } last = $0; i = i + 1 }\ + END { }'\ + $1 > temp.awk.2 + +awk \ + 'BEGIN { }\ + /DATA_SEG_DEFS_HERE/,/BLOCK_STRINGS_BEGIN/ { print }\ + END { }'\ + $1 > temp.awk.3 + +cp $1 $1.orig +cat temp.awk.1 temp.awk.2 temp.awk.3 | sed -e 's/^\.data//' -e 's/^\.bss//' -e 's/^\.text//' > $1 +/bin/rm -f temp.awk.1 temp.awk.2 temp.awk.3 $1.orig diff --git a/package/build.linux b/package/build.linux new file mode 100755 index 0000000..061dad7 --- /dev/null +++ b/package/build.linux @@ -0,0 +1,37 @@ +#!/bin/sh -xe +# clean +clean() +{ + make clean + rm -rf $SRCDIR/*.zip + rm -rf $SRCDIR/*.tar.gz +} + +# build +build() +{ + make bios +} + +# install +install() +{ + echo "$BUILD_TARGET_OS" + if [ "$BUILD_TARGET_OS" = "linux" ] + then + BIN_DIR=$SRCDIR/package/vgabios.package.linux/data + else + BIN_DIR=$SRCDIR/package/vgabios.package.windows/data + fi + BIOS_DIR=$BIN_DIR/Emulator/x86/data/pc-bios + + cd $SRCDIR + mkdir -p $BIOS_DIR + cp VGABIOS-lgpl-latest.bin $BIOS_DIR/vgabios-tizenvga.bin +} + +[ "$1" = "clean" ] && clean +[ "$1" = "build" ] && build +[ "$1" = "install" ] && install + +echo "success" diff --git a/package/pkginfo.manifest b/package/pkginfo.manifest new file mode 100644 index 0000000..1a2791a --- /dev/null +++ b/package/pkginfo.manifest @@ -0,0 +1,15 @@ +Package: vgabios +Version: 1.1.3 +OS: linux +Build-host-os: linux +Maintainer: Yeong-Kyoon, Lee <yeongkyoon.lee@samsung.com> +Source: vgabios +Description: VGA bios for Tizen emulator + +Package: vgabios +Version: 1.1.3 +OS: windows +Build-host-os: linux +Maintainer: Yeong-Kyoon, Lee <yeongkyoon.lee@samsung.com> +Source: vgabios +Description: VGA bios for Tizen emulator diff --git a/tests/CVS/Entries b/tests/CVS/Entries new file mode 100644 index 0000000..374c8f3 --- /dev/null +++ b/tests/CVS/Entries @@ -0,0 +1,2 @@ +/testbios.c/1.1/Mon Feb 18 10:31:49 2002// +D/lfbprof//// diff --git a/tests/CVS/Repository b/tests/CVS/Repository new file mode 100644 index 0000000..ca7e6ea --- /dev/null +++ b/tests/CVS/Repository @@ -0,0 +1 @@ +vgabios/tests diff --git a/tests/CVS/Root b/tests/CVS/Root new file mode 100644 index 0000000..544303b --- /dev/null +++ b/tests/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sv.gnu.org:/sources/vgabios diff --git a/tests/lfbprof/CVS/Entries b/tests/lfbprof/CVS/Entries new file mode 100644 index 0000000..9584a67 --- /dev/null +++ b/tests/lfbprof/CVS/Entries @@ -0,0 +1,4 @@ +/Makefile/1.1/Mon Feb 18 22:07:33 2002// +/lfbprof.c/1.3/Sun Apr 18 09:15:22 2004// +/lfbprof.h/1.2/Mon Feb 18 22:26:31 2002// +D diff --git a/tests/lfbprof/CVS/Repository b/tests/lfbprof/CVS/Repository new file mode 100644 index 0000000..1dc40e3 --- /dev/null +++ b/tests/lfbprof/CVS/Repository @@ -0,0 +1 @@ +vgabios/tests/lfbprof diff --git a/tests/lfbprof/CVS/Root b/tests/lfbprof/CVS/Root new file mode 100644 index 0000000..544303b --- /dev/null +++ b/tests/lfbprof/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.sv.gnu.org:/sources/vgabios diff --git a/tests/lfbprof/Makefile b/tests/lfbprof/Makefile new file mode 100644 index 0000000..7c42e38 --- /dev/null +++ b/tests/lfbprof/Makefile @@ -0,0 +1,5 @@ +# Very simple makefile for LFBPROF.C using Watcom C++ 10.0a with DOS4GW + +lfbprof.exe: lfbprof.c lfbprof.h + wcl386 -zq -s -d2 lfbprof.c + diff --git a/tests/lfbprof/lfbprof.c b/tests/lfbprof/lfbprof.c new file mode 100644 index 0000000..df37452 --- /dev/null +++ b/tests/lfbprof/lfbprof.c @@ -0,0 +1,594 @@ +/**************************************************************************** +* +* VBE 2.0 Linear Framebuffer Profiler +* By Kendall Bennett and Brian Hook +* +* Filename: LFBPROF.C +* Language: ANSI C +* Environment: Watcom C/C++ 10.0a with DOS4GW +* +* Description: Simple program to profile the speed of screen clearing +* and full screen BitBlt operations using a VESA VBE 2.0 +* linear framebuffer from 32 bit protected mode. +* +* For simplicity, this program only supports 256 color +* SuperVGA video modes that support a linear framebuffer. +* +* +* 2002/02/18: Jeroen Janssen <japj at xs4all dot nl> +* - fixed unsigned short for mode list (-1 != 0xffff otherwise) +* - fixed LfbMapRealPointer macro mask problem (some modes were skipped) +* +****************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <conio.h> +#include <dos.h> +#include "lfbprof.h" + +/*---------------------------- Global Variables ---------------------------*/ + +int VESABuf_len = 1024; /* Length of VESABuf */ +int VESABuf_sel = 0; /* Selector for VESABuf */ +int VESABuf_rseg; /* Real mode segment of VESABuf */ +unsigned short modeList[50]; /* List of available VBE modes */ +float clearsPerSec; /* Number of clears per second */ +float clearsMbPerSec; /* Memory transfer for clears */ +float bitBltsPerSec; /* Number of BitBlt's per second */ +float bitBltsMbPerSec; /* Memory transfer for bitblt's */ +int xres,yres; /* Video mode resolution */ +int bytesperline; /* Bytes per scanline for mode */ +long imageSize; /* Length of the video image */ +char *LFBPtr; /* Pointer to linear framebuffer */ + +/*------------------------- DPMI interface routines -----------------------*/ + +void DPMI_allocRealSeg(int size,int *sel,int *r_seg) +/**************************************************************************** +* +* Function: DPMI_allocRealSeg +* Parameters: size - Size of memory block to allocate +* sel - Place to return protected mode selector +* r_seg - Place to return real mode segment +* +* Description: Allocates a block of real mode memory using DPMI services. +* This routine returns both a protected mode selector and +* real mode segment for accessing the memory block. +* +****************************************************************************/ +{ + union REGS r; + + r.w.ax = 0x100; /* DPMI allocate DOS memory */ + r.w.bx = (size + 0xF) >> 4; /* number of paragraphs */ + int386(0x31, &r, &r); + if (r.w.cflag) + FatalError("DPMI_allocRealSeg failed!"); + *sel = r.w.dx; /* Protected mode selector */ + *r_seg = r.w.ax; /* Real mode segment */ +} + +void DPMI_freeRealSeg(unsigned sel) +/**************************************************************************** +* +* Function: DPMI_allocRealSeg +* Parameters: sel - Protected mode selector of block to free +* +* Description: Frees a block of real mode memory. +* +****************************************************************************/ +{ + union REGS r; + + r.w.ax = 0x101; /* DPMI free DOS memory */ + r.w.dx = sel; /* DX := selector from 0x100 */ + int386(0x31, &r, &r); +} + +typedef struct { + long edi; + long esi; + long ebp; + long reserved; + long ebx; + long edx; + long ecx; + long eax; + short flags; + short es,ds,fs,gs,ip,cs,sp,ss; + } _RMREGS; + +#define IN(reg) rmregs.e##reg = in->x.reg +#define OUT(reg) out->x.reg = rmregs.e##reg + +int DPMI_int86(int intno, RMREGS *in, RMREGS *out) +/**************************************************************************** +* +* Function: DPMI_int86 +* Parameters: intno - Interrupt number to issue +* in - Pointer to structure for input registers +* out - Pointer to structure for output registers +* Returns: Value returned by interrupt in AX +* +* Description: Issues a real mode interrupt using DPMI services. +* +****************************************************************************/ +{ + _RMREGS rmregs; + union REGS r; + struct SREGS sr; + + memset(&rmregs, 0, sizeof(rmregs)); + IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di); + + segread(&sr); + r.w.ax = 0x300; /* DPMI issue real interrupt */ + r.h.bl = intno; + r.h.bh = 0; + r.w.cx = 0; + sr.es = sr.ds; + r.x.edi = (unsigned)&rmregs; + int386x(0x31, &r, &r, &sr); /* Issue the interrupt */ + + OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di); + out->x.cflag = rmregs.flags & 0x1; + return out->x.ax; +} + +int DPMI_int86x(int intno, RMREGS *in, RMREGS *out, RMSREGS *sregs) +/**************************************************************************** +* +* Function: DPMI_int86 +* Parameters: intno - Interrupt number to issue +* in - Pointer to structure for input registers +* out - Pointer to structure for output registers +* sregs - Values to load into segment registers +* Returns: Value returned by interrupt in AX +* +* Description: Issues a real mode interrupt using DPMI services. +* +****************************************************************************/ +{ + _RMREGS rmregs; + union REGS r; + struct SREGS sr; + + memset(&rmregs, 0, sizeof(rmregs)); + IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di); + rmregs.es = sregs->es; + rmregs.ds = sregs->ds; + + segread(&sr); + r.w.ax = 0x300; /* DPMI issue real interrupt */ + r.h.bl = intno; + r.h.bh = 0; + r.w.cx = 0; + sr.es = sr.ds; + r.x.edi = (unsigned)&rmregs; + int386x(0x31, &r, &r, &sr); /* Issue the interrupt */ + + OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di); + sregs->es = rmregs.es; + sregs->cs = rmregs.cs; + sregs->ss = rmregs.ss; + sregs->ds = rmregs.ds; + out->x.cflag = rmregs.flags & 0x1; + return out->x.ax; +} + +int DPMI_allocSelector(void) +/**************************************************************************** +* +* Function: DPMI_allocSelector +* Returns: Newly allocated protected mode selector +* +* Description: Allocates a new protected mode selector using DPMI +* services. This selector has a base address and limit of 0. +* +****************************************************************************/ +{ + int sel; + union REGS r; + + r.w.ax = 0; /* DPMI allocate selector */ + r.w.cx = 1; /* Allocate a single selector */ + int386(0x31, &r, &r); + if (r.x.cflag) + FatalError("DPMI_allocSelector() failed!"); + sel = r.w.ax; + + r.w.ax = 9; /* DPMI set access rights */ + r.w.bx = sel; + r.w.cx = 0x8092; /* 32 bit page granular */ + int386(0x31, &r, &r); + return sel; +} + +long DPMI_mapPhysicalToLinear(long physAddr,long limit) +/**************************************************************************** +* +* Function: DPMI_mapPhysicalToLinear +* Parameters: physAddr - Physical memory address to map +* limit - Length-1 of physical memory region to map +* Returns: Starting linear address for mapped memory +* +* Description: Maps a section of physical memory into the linear address +* space of a process using DPMI calls. Note that this linear +* address cannot be used directly, but must be used as the +* base address for a selector. +* +****************************************************************************/ +{ + union REGS r; + + r.w.ax = 0x800; /* DPMI map physical to linear */ + r.w.bx = physAddr >> 16; + r.w.cx = physAddr & 0xFFFF; + r.w.si = limit >> 16; + r.w.di = limit & 0xFFFF; + int386(0x31, &r, &r); + if (r.x.cflag) + FatalError("DPMI_mapPhysicalToLinear() failed!"); + return ((long)r.w.bx << 16) + r.w.cx; +} + +void DPMI_setSelectorBase(int sel,long linAddr) +/**************************************************************************** +* +* Function: DPMI_setSelectorBase +* Parameters: sel - Selector to change base address for +* linAddr - Linear address used for new base address +* +* Description: Sets the base address for the specified selector. +* +****************************************************************************/ +{ + union REGS r; + + r.w.ax = 7; /* DPMI set selector base address */ + r.w.bx = sel; + r.w.cx = linAddr >> 16; + r.w.dx = linAddr & 0xFFFF; + int386(0x31, &r, &r); + if (r.x.cflag) + FatalError("DPMI_setSelectorBase() failed!"); +} + +void DPMI_setSelectorLimit(int sel,long limit) +/**************************************************************************** +* +* Function: DPMI_setSelectorLimit +* Parameters: sel - Selector to change limit for +* limit - Limit-1 for the selector +* +* Description: Sets the memory limit for the specified selector. +* +****************************************************************************/ +{ + union REGS r; + + r.w.ax = 8; /* DPMI set selector limit */ + r.w.bx = sel; + r.w.cx = limit >> 16; + r.w.dx = limit & 0xFFFF; + int386(0x31, &r, &r); + if (r.x.cflag) + FatalError("DPMI_setSelectorLimit() failed!"); +} + +/*-------------------------- VBE Interface routines -----------------------*/ + +void FatalError(char *msg) +{ + fprintf(stderr,"%s\n", msg); + exit(1); +} + +static void ExitVBEBuf(void) +{ + DPMI_freeRealSeg(VESABuf_sel); +} + +void VBE_initRMBuf(void) +/**************************************************************************** +* +* Function: VBE_initRMBuf +* Description: Initialises the VBE transfer buffer in real mode memory. +* This routine is called by the VESAVBE module every time +* it needs to use the transfer buffer, so we simply allocate +* it once and then return. +* +****************************************************************************/ +{ + if (!VESABuf_sel) { + DPMI_allocRealSeg(VESABuf_len, &VESABuf_sel, &VESABuf_rseg); + atexit(ExitVBEBuf); + } +} + +void VBE_callESDI(RMREGS *regs, void *buffer, int size) +/**************************************************************************** +* +* Function: VBE_callESDI +* Parameters: regs - Registers to load when calling VBE +* buffer - Buffer to copy VBE info block to +* size - Size of buffer to fill +* +* Description: Calls the VESA VBE and passes in a buffer for the VBE to +* store information in, which is then copied into the users +* buffer space. This works in protected mode as the buffer +* passed to the VESA VBE is allocated in conventional +* memory, and is then copied into the users memory block. +* +****************************************************************************/ +{ + RMSREGS sregs; + + VBE_initRMBuf(); + sregs.es = VESABuf_rseg; + regs->x.di = 0; + _fmemcpy(MK_FP(VESABuf_sel,0),buffer,size); + DPMI_int86x(0x10, regs, regs, &sregs); + _fmemcpy(buffer,MK_FP(VESABuf_sel,0),size); +} + +int VBE_detect(void) +/**************************************************************************** +* +* Function: VBE_detect +* Parameters: vgaInfo - Place to store the VGA information block +* Returns: VBE version number, or 0 if not detected. +* +* Description: Detects if a VESA VBE is out there and functioning +* correctly. If we detect a VBE interface we return the +* VGAInfoBlock returned by the VBE and the VBE version number. +* +****************************************************************************/ +{ + RMREGS regs; + unsigned short *p1,*p2; + VBE_vgaInfo vgaInfo; + + /* Put 'VBE2' into the signature area so that the VBE 2.0 BIOS knows + * that we have passed a 512 byte extended block to it, and wish + * the extended information to be filled in. + */ + strncpy(vgaInfo.VESASignature,"VBE2",4); + + /* Get the SuperVGA Information block */ + regs.x.ax = 0x4F00; + VBE_callESDI(®s, &vgaInfo, sizeof(VBE_vgaInfo)); + if (regs.x.ax != 0x004F) + return 0; + if (strncmp(vgaInfo.VESASignature,"VESA",4) != 0) + return 0; + + /* Now that we have detected a VBE interface, copy the list of available + * video modes into our local buffer. We *must* copy this mode list, + * since the VBE will build the mode list in the VBE_vgaInfo buffer + * that we have passed, so the next call to the VBE will trash the + * list of modes. + */ + printf("videomodeptr %x\n",vgaInfo.VideoModePtr); + p1 = LfbMapRealPointer(vgaInfo.VideoModePtr); + p2 = modeList; + while (*p1 != -1) + { + printf("found mode %x\n",*p1); + *p2++ = *p1++; + } + *p2 = -1; + return vgaInfo.VESAVersion; +} + +int VBE_getModeInfo(int mode,VBE_modeInfo *modeInfo) +/**************************************************************************** +* +* Function: VBE_getModeInfo +* Parameters: mode - VBE mode to get information for +* modeInfo - Place to store VBE mode information +* Returns: 1 on success, 0 if function failed. +* +* Description: Obtains information about a specific video mode from the +* VBE. You should use this function to find the video mode +* you wish to set, as the new VBE 2.0 mode numbers may be +* completely arbitrary. +* +****************************************************************************/ +{ + RMREGS regs; + + regs.x.ax = 0x4F01; /* Get mode information */ + regs.x.cx = mode; + VBE_callESDI(®s, modeInfo, sizeof(VBE_modeInfo)); + if (regs.x.ax != 0x004F) + return 0; + if ((modeInfo->ModeAttributes & vbeMdAvailable) == 0) + return 0; + return 1; +} + +void VBE_setVideoMode(int mode) +/**************************************************************************** +* +* Function: VBE_setVideoMode +* Parameters: mode - VBE mode number to initialise +* +****************************************************************************/ +{ + RMREGS regs; + regs.x.ax = 0x4F02; + regs.x.bx = mode; + DPMI_int86(0x10,®s,®s); +} + +/*-------------------- Application specific routines ----------------------*/ + +void *GetPtrToLFB(long physAddr) +/**************************************************************************** +* +* Function: GetPtrToLFB +* Parameters: physAddr - Physical memory address of linear framebuffer +* Returns: Far pointer to the linear framebuffer memory +* +****************************************************************************/ +{ + int sel; + long linAddr,limit = (4096 * 1024) - 1; + +// sel = DPMI_allocSelector(); + linAddr = DPMI_mapPhysicalToLinear(physAddr,limit); +// DPMI_setSelectorBase(sel,linAddr); +// DPMI_setSelectorLimit(sel,limit); +// return MK_FP(sel,0); + return (void*)linAddr; +} + +void AvailableModes(void) +/**************************************************************************** +* +* Function: AvailableModes +* +* Description: Display a list of available LFB mode resolutions. +* +****************************************************************************/ +{ + unsigned short *p; + VBE_modeInfo modeInfo; + + printf("Usage: LFBPROF <xres> <yres>\n\n"); + printf("Available 256 color video modes:\n"); + for (p = modeList; *p != -1; p++) { + if (VBE_getModeInfo(*p, &modeInfo)) { + /* Filter out only 8 bit linear framebuffer modes */ + if ((modeInfo.ModeAttributes & vbeMdLinear) == 0) + continue; + if (modeInfo.MemoryModel != vbeMemPK + || modeInfo.BitsPerPixel != 8 + || modeInfo.NumberOfPlanes != 1) + continue; + printf(" %4d x %4d %d bits per pixel\n", + modeInfo.XResolution, modeInfo.YResolution, + modeInfo.BitsPerPixel); + } + } + exit(1); +} + +void InitGraphics(int x,int y) +/**************************************************************************** +* +* Function: InitGraphics +* Parameters: x,y - Requested video mode resolution +* +* Description: Initialise the specified video mode. We search through +* the list of available video modes for one that matches +* the resolution and color depth are are looking for. +* +****************************************************************************/ +{ + unsigned short *p; + VBE_modeInfo modeInfo; + printf("InitGraphics\n"); + + for (p = modeList; *p != -1; p++) { + if (VBE_getModeInfo(*p, &modeInfo)) { + /* Filter out only 8 bit linear framebuffer modes */ + if ((modeInfo.ModeAttributes & vbeMdLinear) == 0) + continue; + if (modeInfo.MemoryModel != vbeMemPK + || modeInfo.BitsPerPixel != 8 + || modeInfo.NumberOfPlanes != 1) + continue; + if (modeInfo.XResolution != x || modeInfo.YResolution != y) + continue; + xres = x; + yres = y; + bytesperline = modeInfo.BytesPerScanLine; + imageSize = bytesperline * yres; + VBE_setVideoMode(*p | vbeUseLFB); + LFBPtr = GetPtrToLFB(modeInfo.PhysBasePtr); + return; + } + } + printf("Valid video mode not found\n"); + exit(1); +} + +void EndGraphics(void) +/**************************************************************************** +* +* Function: EndGraphics +* +* Description: Restores text mode. +* +****************************************************************************/ +{ + RMREGS regs; + printf("EndGraphics\n"); + regs.x.ax = 0x3; + DPMI_int86(0x10, ®s, ®s); +} + +void ProfileMode(void) +/**************************************************************************** +* +* Function: ProfileMode +* +* Description: Profiles framebuffer performance for simple screen clearing +* and for copying from system memory to video memory (BitBlt). +* This routine thrashes the CPU cache by cycling through +* enough system memory buffers to invalidate the entire +* CPU external cache before re-using the first memory buffer +* again. +* +****************************************************************************/ +{ + int i,numClears,numBlts,maxImages; + long startTicks,endTicks; + void *image[10],*dst; + printf("ProfileMode\n"); + + /* Profile screen clearing operation */ + startTicks = LfbGetTicks(); + numClears = 0; + while ((LfbGetTicks() - startTicks) < 182) + LfbMemset(LFBPtr,numClears++,imageSize); + endTicks = LfbGetTicks(); + clearsPerSec = numClears / ((endTicks - startTicks) * 0.054925); + clearsMbPerSec = (clearsPerSec * imageSize) / 1048576.0; + + /* Profile system memory to video memory copies */ + maxImages = ((512 * 1024U) / imageSize) + 2; + for (i = 0; i < maxImages; i++) { + image[i] = malloc(imageSize); + if (image[i] == NULL) + FatalError("Not enough memory to profile BitBlt!"); + memset(image[i],i+1,imageSize); + } + startTicks = LfbGetTicks(); + numBlts = 0; + while ((LfbGetTicks() - startTicks) < 182) + LfbMemcpy(LFBPtr,image[numBlts++ % maxImages],imageSize); + endTicks = LfbGetTicks(); + bitBltsPerSec = numBlts / ((endTicks - startTicks) * 0.054925); + bitBltsMbPerSec = (bitBltsPerSec * imageSize) / 1048576.0; +} + +void main(int argc, char *argv[]) +{ + if (VBE_detect() < 0x200) + FatalError("This program requires VBE 2.0; Please install UniVBE 5.1."); + if (argc != 3) + AvailableModes(); /* Display available modes */ + + InitGraphics(atoi(argv[1]),atoi(argv[2])); /* Start graphics */ + ProfileMode(); /* Profile the video mode */ + EndGraphics(); /* Restore text mode */ + + printf("Profiling results for %dx%d 8 bits per pixel.\n",xres,yres); + printf("%3.2f clears/s, %2.2f Mb/s\n", clearsPerSec, clearsMbPerSec); + printf("%3.2f bitBlt/s, %2.2f Mb/s\n", bitBltsPerSec, bitBltsMbPerSec); +} diff --git a/tests/lfbprof/lfbprof.h b/tests/lfbprof/lfbprof.h new file mode 100644 index 0000000..bae0e09 --- /dev/null +++ b/tests/lfbprof/lfbprof.h @@ -0,0 +1,149 @@ +/**************************************************************************** +* +* VBE 2.0 Linear Framebuffer Profiler +* By Kendall Bennett and Brian Hook +* +* Filename: LFBPROF.H +* Language: ANSI C +* Environment: Watcom C/C++ 10.0a with DOS4GW +* +* Description: Header file for the LFBPROF.C progam. +* +****************************************************************************/ + +#ifndef __LFBPROF_H +#define __LFBPROF_H + +/*---------------------- Macros and type definitions ----------------------*/ + +#pragma pack(1) + +/* SuperVGA information block */ + +typedef struct { + char VESASignature[4]; /* 'VESA' 4 byte signature */ + short VESAVersion; /* VBE version number */ + long OemStringPtr; /* Pointer to OEM string */ + long Capabilities; /* Capabilities of video card */ + long VideoModePtr; /* Pointer to supported modes */ + short TotalMemory; /* Number of 64kb memory blocks */ + + /* VBE 2.0 extensions */ + + short OemSoftwareRev; /* OEM Software revision number */ + long OemVendorNamePtr; /* Pointer to Vendor Name string */ + long OemProductNamePtr; /* Pointer to Product Name string */ + long OemProductRevPtr; /* Pointer to Product Revision str */ + char reserved[222]; /* Pad to 256 byte block size */ + char OemDATA[256]; /* Scratch pad for OEM data */ + } VBE_vgaInfo; + +/* SuperVGA mode information block */ + +typedef struct { + short ModeAttributes; /* Mode attributes */ + char WinAAttributes; /* Window A attributes */ + char WinBAttributes; /* Window B attributes */ + short WinGranularity; /* Window granularity in k */ + short WinSize; /* Window size in k */ + short WinASegment; /* Window A segment */ + short WinBSegment; /* Window B segment */ + long WinFuncPtr; /* Pointer to window function */ + short BytesPerScanLine; /* Bytes per scanline */ + short XResolution; /* Horizontal resolution */ + short YResolution; /* Vertical resolution */ + char XCharSize; /* Character cell width */ + char YCharSize; /* Character cell height */ + char NumberOfPlanes; /* Number of memory planes */ + char BitsPerPixel; /* Bits per pixel */ + char NumberOfBanks; /* Number of CGA style banks */ + char MemoryModel; /* Memory model type */ + char BankSize; /* Size of CGA style banks */ + char NumberOfImagePages; /* Number of images pages */ + char res1; /* Reserved */ + char RedMaskSize; /* Size of direct color red mask */ + char RedFieldPosition; /* Bit posn of lsb of red mask */ + char GreenMaskSize; /* Size of direct color green mask */ + char GreenFieldPosition; /* Bit posn of lsb of green mask */ + char BlueMaskSize; /* Size of direct color blue mask */ + char BlueFieldPosition; /* Bit posn of lsb of blue mask */ + char RsvdMaskSize; /* Size of direct color res mask */ + char RsvdFieldPosition; /* Bit posn of lsb of res mask */ + char DirectColorModeInfo; /* Direct color mode attributes */ + + /* VBE 2.0 extensions */ + + long PhysBasePtr; /* Physical address for linear buf */ + long OffScreenMemOffset; /* Pointer to start of offscreen mem*/ + short OffScreenMemSize; /* Amount of offscreen mem in 1K's */ + char res2[206]; /* Pad to 256 byte block size */ + } VBE_modeInfo; + +#define vbeMemPK 4 /* Packed Pixel memory model */ +#define vbeUseLFB 0x4000 /* Enable linear framebuffer mode */ + +/* Flags for the mode attributes returned by VBE_getModeInfo. If + * vbeMdNonBanked is set to 1 and vbeMdLinear is also set to 1, then only + * the linear framebuffer mode is available. + */ + +#define vbeMdAvailable 0x0001 /* Video mode is available */ +#define vbeMdColorMode 0x0008 /* Mode is a color video mode */ +#define vbeMdGraphMode 0x0010 /* Mode is a graphics mode */ +#define vbeMdNonBanked 0x0040 /* Banked mode is not supported */ +#define vbeMdLinear 0x0080 /* Linear mode supported */ + +/* Structures for issuing real mode interrupts with DPMI */ + +struct _RMWORDREGS { + unsigned short ax, bx, cx, dx, si, di, cflag; + }; + +struct _RMBYTEREGS { + unsigned char al, ah, bl, bh, cl, ch, dl, dh; + }; + +typedef union { + struct _RMWORDREGS x; + struct _RMBYTEREGS h; + } RMREGS; + +typedef struct { + unsigned short es; + unsigned short cs; + unsigned short ss; + unsigned short ds; + } RMSREGS; + +/* Inline assembler block fill/move routines */ + +void LfbMemset(void *p,int c,int n); +#pragma aux LfbMemset = \ + "shr ecx,2" \ + "xor eax,eax" \ + "mov al,bl" \ + "shl ebx,8" \ + "or ax,bx" \ + "mov ebx,eax" \ + "shl ebx,16" \ + "or eax,ebx" \ + "rep stosd" \ + parm [edi] [ebx] [ecx]; + +void LfbMemcpy(void *dst,void *src,int n); +#pragma aux LfbMemcpy = \ + "shr ecx,2" \ + "rep movsd" \ + parm [edi] [esi] [ecx]; + +/* Map a real mode pointer into address space */ + +#define LfbMapRealPointer(p) (void*)(((unsigned)((p) & 0xFFFF0000) >> 12) + ((p) & 0xFFFF)) + +/* Get the current timer tick count */ + +#define LfbGetTicks() *((long*)0x46C) + +#pragma pack() + +#endif /* __LFBPROF_H */ diff --git a/tests/testbios.c b/tests/testbios.c new file mode 100644 index 0000000..99da5a6 --- /dev/null +++ b/tests/testbios.c @@ -0,0 +1,353 @@ +/*
+ This is a little turbo C program that executes
+ several int10, and let you inspect the content
+ of the vgabios area
+
+ It is used to test the behavior of the vgabios
+*/
+
+#include <stdio.h>
+#include <dos.h>
+#include <conio.h>
+
+
+typedef unsigned char Bit8u;
+typedef unsigned short Bit16u;
+
+typedef struct
+{Bit8u initial;
+ Bit8u current;
+ Bit16u nbcols;
+ Bit16u regen;
+ Bit16u start;
+ Bit16u curpos[8];
+ Bit8u curtyp;
+ Bit8u curpage;
+ Bit16u crtc;
+ Bit16u msr;
+ Bit16u cgapal;
+ Bit8u nbrows;
+ Bit16u cheight;
+ Bit8u ctl;
+ Bit8u switches;
+ Bit8u modeset;
+ Bit8u dcc;
+ Bit16u vsseg;
+ Bit16u vsoffset;
+} BIOSAREA;
+
+void int10ax0003(struct REGPACK *regs)
+{
+ regs->r_ax=0x0003;
+ intr(0x10,regs);
+}
+
+void int10ax02(struct REGPACK *regs)
+{
+ regs->r_ax=0x0200;
+ regs->r_bx=0x0000;
+ regs->r_dx=0x1710;
+ intr(0x10,regs);
+ printf("We are now at 24/17");
+}
+
+void int10ax03(struct REGPACK *regs)
+{
+ regs->r_ax=0x0300;
+ regs->r_bx=0x0000;
+ intr(0x10,regs);
+ printf("\nCursor is ax%04x cx%04x dx%04x\n",regs->r_ax,regs->r_cx,regs->r_dx);
+}
+
+void int10ax0501(struct REGPACK *regs)
+{
+ regs->r_ax=0x0501;
+ intr(0x10,regs);
+ regs->r_ax=0x0e61;
+ regs->r_bx=0x0000;
+ intr(0x10,regs);
+ printf("We are now on page 2");
+}
+
+void int10ax0602(struct REGPACK *regs)
+{
+ regs->r_ax=0x0602;
+ regs->r_bx=0x0700;
+ regs->r_cx=0x0101;
+ regs->r_dx=0x0a0a;
+ intr(0x10,regs);
+ printf("Scrolled 2 up");
+}
+
+void int10ax0702(struct REGPACK *regs)
+{
+ regs->r_ax=0x0702;
+ regs->r_bx=0x0700;
+ regs->r_cx=0x0101;
+ regs->r_dx=0x0a0a;
+ intr(0x10,regs);
+ printf("Scrolled 2 down");
+}
+
+void int10ax08(struct REGPACK *regs)
+{
+ regs->r_ax=0x0800;
+ regs->r_bx=0x0000;
+ intr(0x10,regs);
+}
+
+void int10ax09(struct REGPACK *regs)
+{
+ char attr;
+ regs->r_ax=0x0501;
+ intr(0x10,regs);
+ for(attr=0;attr<16;attr++)
+ {printf("%02x ",attr);
+ regs->r_ax=0x0961+attr;
+ regs->r_bx=0x0100+attr;
+ regs->r_cx=0x0016;
+ intr(0x10,regs);
+ printf("\n");
+ }
+}
+
+void int10ax0a(struct REGPACK *regs)
+{
+ regs->r_ax=0x0501;
+ intr(0x10,regs);
+ regs->r_ax=0x0a62;
+ regs->r_bx=0x0101;
+ regs->r_cx=0x0016;
+ intr(0x10,regs);
+}
+
+void int10ax0f(struct REGPACK *regs)
+{
+ regs->r_ax=0x0501;
+ intr(0x10,regs);
+ regs->r_ax=0x0f00;
+ intr(0x10,regs);
+}
+
+void int10ax1b(struct REGPACK *regs)
+{unsigned char table[64];
+ unsigned char far *ptable;
+ int i;
+
+ regs->r_ax=0x0501;
+ intr(0x10,regs);
+ regs->r_ax=0x1b00;
+ regs->r_bx=0x0000;
+ ptable=&table;
+ regs->r_es=FP_SEG(ptable);
+ regs->r_di=FP_OFF(ptable);
+ printf("Read state info in %04x:%04x\n",regs->r_es,regs->r_di);
+ intr(0x10,regs);
+
+ for(i=0;i<64;i++)
+ {if(i%16==0)printf("\n%02x ",i);
+ printf("%02x ",table[i]);
+ }
+ printf("\n");
+}
+
+static unsigned char var[64];
+
+void int10ax13(struct REGPACK *regs)
+{unsigned char far *pvar;
+
+ pvar=&var;
+
+ regs->r_ax=0x1300;
+ regs->r_bx=0x000b;
+ regs->r_dx=0x1010;
+ regs->r_cx=0x0002;
+ regs->r_es=FP_SEG(pvar);
+ regs->r_bp=FP_OFF(pvar);
+ pokeb(regs->r_es,regs->r_bp,'t');
+ pokeb(regs->r_es,regs->r_bp+1,'b');
+ printf("Writing from %04x:%04x\n",regs->r_es,regs->r_bp);
+ intr(0x10,regs);
+
+}
+
+void switch_50(struct REGPACK *regs)
+{
+ regs->r_ax=0x1202;
+ regs->r_bx=0x3000;
+ intr(0x10,regs);
+ regs->r_ax=0x0003;
+ intr(0x10,regs);
+ regs->r_ax=0x1112;
+ regs->r_bx=0x0000;
+ intr(0x10,regs);
+}
+
+char exec_function(struct REGPACK *regs)
+{char c;
+
+ printf("--- Functions --------------------\n");
+ printf("a. int10 ax0003\t");
+ printf("b. int10 ax02\t");
+ printf("c. int10 ax03\t");
+ printf("d. int10 ax0501\n");
+ printf("e. int10 ax0602\t");
+ printf("f. int10 ax0702\t");
+ printf("g. int10 ax08\t");
+ printf("h. int10 ax09\t");
+ printf("i. int10 ax0a\n");
+ printf("j. int10 ax0f\t");
+ printf("k. int10 ax1b\t");
+ printf("l. int10 ax13\n");
+ printf("q. Quit\t");
+ printf("r. switch to 50 lines\n");
+ c=getche();
+
+ switch(c)
+ {case 'a':
+ int10ax0003(regs);
+ break;
+ case 'b':
+ int10ax02(regs);
+ break;
+ case 'c':
+ int10ax03(regs);
+ break;
+ case 'd':
+ int10ax0501(regs);
+ break;
+ case 'e':
+ int10ax0602(regs);
+ break;
+ case 'f':
+ int10ax0702(regs);
+ break;
+ case 'g':
+ int10ax08(regs);
+ break;
+ case 'h':
+ int10ax09(regs);
+ break;
+ case 'i':
+ int10ax0a(regs);
+ break;
+ case 'j':
+ int10ax0f(regs);
+ break;
+ case 'k':
+ int10ax1b(regs);
+ break;
+ case 'l':
+ int10ax13(regs);
+ break;
+ case 'q':
+ break;
+ case 'r':
+ switch_50(regs);
+ break;
+ default:
+ printf("No such function!\n");
+ }
+
+ if(c=='q')return 1;
+ while(kbhit()==0);
+ c=getch();
+
+ return 0;
+}
+
+void read_bios_area(BIOSAREA *biosarea)
+{
+ biosarea->initial=peekb(0x40,0x10);
+ biosarea->current=peekb(0x40,0x49);
+ biosarea->nbcols=peek(0x40,0x4a);
+ biosarea->regen=peek(0x40,0x4c);
+ biosarea->start=peek(0x40,0x4e);
+ biosarea->curpos[0]=peek(0x40,0x50);
+ biosarea->curpos[1]=peek(0x40,0x52);
+ biosarea->curpos[2]=peek(0x40,0x54);
+ biosarea->curpos[3]=peek(0x40,0x56);
+ biosarea->curpos[4]=peek(0x40,0x58);
+ biosarea->curpos[5]=peek(0x40,0x5a);
+ biosarea->curpos[6]=peek(0x40,0x5c);
+ biosarea->curpos[7]=peek(0x40,0x5e);
+ biosarea->curtyp=peek(0x40,0x60);
+ biosarea->curpage=peekb(0x40,0x62);
+ biosarea->crtc=peek(0x40,0x63);
+ biosarea->msr=peekb(0x40,0x65);
+ biosarea->cgapal=peekb(0x40,0x66);
+ biosarea->nbrows=peekb(0x40,0x84);
+ biosarea->cheight=peek(0x40,0x85);
+ biosarea->ctl=peekb(0x40,0x87);
+ biosarea->switches=peekb(0x40,0x88);
+ biosarea->modeset=peekb(0x40,0x89);
+ biosarea->dcc=peekb(0x40,0x8a);
+ biosarea->vsseg=peek(0x40,0xa8);
+ biosarea->vsoffset=peek(0x40,0xaa);
+}
+
+void show_bios_area(BIOSAREA *biosarea)
+{
+ printf("--- BIOS area --------------------\n");
+ printf("initial : %02x\t",biosarea->initial);
+ printf("current : %02x\t",biosarea->current);
+ printf("nbcols : %04x\t",biosarea->nbcols);
+ printf("regen : %04x\t",biosarea->regen);
+ printf("start : %04x\n",biosarea->start);
+ printf("curpos : %04x %04x %04x %04x %04x %04x %04x %04x\n",
+ biosarea->curpos[0], biosarea->curpos[1], biosarea->curpos[2], biosarea->curpos[3],
+ biosarea->curpos[4], biosarea->curpos[5], biosarea->curpos[6], biosarea->curpos[7]);
+ printf("curtyp : %04x\t",biosarea->curtyp);
+ printf("curpage : %02x\t",biosarea->curpage);
+ printf("crtc : %04x\t",biosarea->crtc);
+ printf("msr : %04x\n",biosarea->msr);
+ printf("cgapal : %04x\t",biosarea->cgapal);
+ printf("nbrows-1: %02x\t",biosarea->nbrows);
+ printf("cheight : %04x\t",biosarea->cheight);
+ printf("ctl : %02x\n",biosarea->ctl);
+ printf("switches: %02x\t",biosarea->switches);
+ printf("modeset : %02x\t",biosarea->modeset);
+ printf("dcc : %02x\t",biosarea->dcc);
+ printf("vs : %04x:%04x\n",biosarea->vsseg,biosarea->vsoffset);
+}
+
+void show_regs(struct REGPACK *regs)
+{
+ printf("--- Registers --------------------\n");
+ printf("ax %04x\t",regs->r_ax);
+ printf("bx %04x\t",regs->r_bx);
+ printf("cx %04x\t",regs->r_cx);
+ printf("dx %04x\t",regs->r_dx);
+ printf("ds %04x\t",regs->r_ds);
+ printf("si %04x\t",regs->r_si);
+ printf("es %04x\t",regs->r_es);
+ printf("di %04x\n",regs->r_di);
+}
+
+void reset_videomode()
+{
+ struct REGPACK regs;
+
+ regs.r_ax=0x0003;
+ intr(0x10,®s);
+}
+
+void main()
+{
+
+ BIOSAREA biosarea;
+ struct REGPACK regs;
+
+ directvideo=0;
+
+ while(1)
+ {
+ read_bios_area(&biosarea);
+
+ reset_videomode();
+ show_bios_area(&biosarea);
+ show_regs(®s);
+
+ if(exec_function(®s)!=0)break;
+ }
+}
@@ -0,0 +1,1457 @@ +// ============================================================================================ +// +// Copyright (C) 2002 Jeroen Janssen +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// ============================================================================================ +// +// This VBE is part of the VGA Bios specific to the plex86/bochs Emulated VGA card. +// You can NOT drive any physical vga card with it. +// +// ============================================================================================ +// +// This VBE Bios is based on information taken from : +// - VESA BIOS EXTENSION (VBE) Core Functions Standard Version 3.0 located at www.vesa.org +// +// ============================================================================================ + + +// defines available + +// disable VESA/VBE2 check in vbe info +//#define VBE2_NO_VESA_CHECK + + +#include "vbe.h" +#include "vbetables.h" + +// The current OEM Software Revision of this VBE Bios +#define VBE_OEM_SOFTWARE_REV 0x0002; + +extern char vbebios_copyright; +extern char vbebios_vendor_name; +extern char vbebios_product_name; +extern char vbebios_product_revision; + +ASM_START +// FIXME: 'merge' these (c) etc strings with the vgabios.c strings? +_vbebios_copyright: +.ascii "Bochs/Plex86 VBE(C) 2003 http://savannah.nongnu.org/projects/vgabios/" +.byte 0x00 + +_vbebios_vendor_name: +.ascii "Bochs/Plex86 Developers" +.byte 0x00 + +_vbebios_product_name: +.ascii "Bochs/Plex86 VBE Adapter" +.byte 0x00 + +_vbebios_product_revision: +.ascii "$Id: vbe.c,v 1.63 2011/04/14 16:10:09 vruppert Exp $" +.byte 0x00 + +_vbebios_info_string: +.ascii "Bochs VBE Display Adapter enabled" +.byte 0x0a,0x0d +.byte 0x0a,0x0d +.byte 0x00 + +_no_vbebios_info_string: +.ascii "NO Bochs VBE Support available!" +.byte 0x0a,0x0d +.byte 0x0a,0x0d +.byte 0x00 + +#if defined(USE_BX_INFO) || defined(DEBUG) +msg_vbe_init: +.ascii "VBE Bios $Id: vbe.c,v 1.63 2011/04/14 16:10:09 vruppert Exp $" +.byte 0x0a,0x0d, 0x00 +#endif + + .align 2 +vesa_pm_start: + dw vesa_pm_set_window - vesa_pm_start + dw vesa_pm_set_display_start - vesa_pm_start + dw vesa_pm_unimplemented - vesa_pm_start + dw vesa_pm_io_ports_table - vesa_pm_start +vesa_pm_io_ports_table: + dw VBE_DISPI_IOPORT_INDEX + dw VBE_DISPI_IOPORT_INDEX + 1 + dw VBE_DISPI_IOPORT_DATA + dw VBE_DISPI_IOPORT_DATA + 1 + dw 0xffff + dw 0xffff + + USE32 +vesa_pm_set_window: + cmp bx, #0x00 + je vesa_pm_set_display_window1 + mov ax, #0x0100 + ret +vesa_pm_set_display_window1: + mov ax, dx + push dx + push ax + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_BANK + out dx, ax + pop ax + mov dx, # VBE_DISPI_IOPORT_DATA + out dx, ax + in ax, dx + pop dx + cmp dx, ax + jne illegal_window + mov ax, #0x004f + ret +illegal_window: + mov ax, #0x014f + ret + +vesa_pm_set_display_start: + cmp bl, #0x80 + je vesa_pm_set_display_start1 + cmp bl, #0x00 + je vesa_pm_set_display_start1 + mov ax, #0x0100 + ret +vesa_pm_set_display_start1: +; convert offset to (X, Y) coordinate +; (would be simpler to change Bochs VBE API...) + push eax + push ecx + push edx + push esi + push edi + shl edx, #16 + and ecx, #0xffff + or ecx, edx + shl ecx, #2 + mov eax, ecx + + push eax + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH + out dx, ax + mov dx, # VBE_DISPI_IOPORT_DATA + in ax, dx + movzx ecx, ax + + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_BPP + out dx, ax + mov dx, # VBE_DISPI_IOPORT_DATA + in ax, dx + movzx esi, ax + pop eax + + cmp esi, #4 + jz bpp4_mode + add esi, #7 + shr esi, #3 + imul ecx, esi + xor edx, edx + div ecx + mov edi, eax + mov eax, edx + xor edx, edx + div esi + jmp set_xy_regs + +bpp4_mode: + shr ecx, #1 + xor edx, edx + div ecx + mov edi, eax + mov eax, edx + shl eax, #1 + +set_xy_regs: + push dx + push ax + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_X_OFFSET + out dx, ax + pop ax + mov dx, # VBE_DISPI_IOPORT_DATA + out dx, ax + pop dx + + mov ax, di + push dx + push ax + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_Y_OFFSET + out dx, ax + pop ax + mov dx, # VBE_DISPI_IOPORT_DATA + out dx, ax + pop dx + + pop edi + pop esi + pop edx + pop ecx + pop eax + mov ax, #0x004f + ret + +vesa_pm_unimplemented: + mov ax, #0x014f + ret + USE16 +vesa_pm_end: + +; DISPI ioport functions + +dispi_get_id: + push dx + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_ID + out dx, ax + mov dx, # VBE_DISPI_IOPORT_DATA + in ax, dx + pop dx + ret + +dispi_set_id: + push dx + push ax + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_ID + out dx, ax + pop ax + mov dx, # VBE_DISPI_IOPORT_DATA + out dx, ax + pop dx + ret +ASM_END + +static void dispi_set_xres(xres) + Bit16u xres; +{ +ASM_START + push bp + mov bp, sp + push ax + push dx + + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_XRES + out dx, ax + mov dx, # VBE_DISPI_IOPORT_DATA + mov ax, 4[bp] ; xres + out dx, ax + + pop dx + pop ax + pop bp +ASM_END +} + +static void dispi_set_yres(yres) + Bit16u yres; +{ + outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_YRES); + outw(VBE_DISPI_IOPORT_DATA,yres); +} + +static void dispi_set_bpp(bpp) + Bit16u bpp; +{ + outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_BPP); + outw(VBE_DISPI_IOPORT_DATA,bpp); +} + +ASM_START +; AL = bits per pixel / AH = bytes per pixel +dispi_get_bpp: + push dx + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_BPP + out dx, ax + mov dx, # VBE_DISPI_IOPORT_DATA + in ax, dx + mov ah, al + shr ah, 3 + test al, #0x07 + jz get_bpp_noinc + inc ah +get_bpp_noinc: + pop dx + ret + +; get display capabilities + +_dispi_get_max_xres: + push dx + push bx + call dispi_get_enable + mov bx, ax + or ax, # VBE_DISPI_GETCAPS + call _dispi_set_enable + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_XRES + out dx, ax + mov dx, # VBE_DISPI_IOPORT_DATA + in ax, dx + push ax + mov ax, bx + call _dispi_set_enable + pop ax + pop bx + pop dx + ret + +_dispi_get_max_bpp: + push dx + push bx + call dispi_get_enable + mov bx, ax + or ax, # VBE_DISPI_GETCAPS + call _dispi_set_enable + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_BPP + out dx, ax + mov dx, # VBE_DISPI_IOPORT_DATA + in ax, dx + push ax + mov ax, bx + call _dispi_set_enable + pop ax + pop bx + pop dx + ret + +_dispi_set_enable: + push dx + push ax + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_ENABLE + out dx, ax + pop ax + mov dx, # VBE_DISPI_IOPORT_DATA + out dx, ax + pop dx + ret + +dispi_get_enable: + push dx + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_ENABLE + out dx, ax + mov dx, # VBE_DISPI_IOPORT_DATA + in ax, dx + pop dx + ret + +_dispi_set_bank: + push dx + push ax + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_BANK + out dx, ax + pop ax + mov dx, # VBE_DISPI_IOPORT_DATA + out dx, ax + pop dx + ret + +dispi_get_bank: + push dx + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_BANK + out dx, ax + mov dx, # VBE_DISPI_IOPORT_DATA + in ax, dx + pop dx + ret +ASM_END + +static void dispi_set_bank_farcall() +{ +ASM_START + cmp bx,#0x0100 + je dispi_set_bank_farcall_get + or bx,bx + jnz dispi_set_bank_farcall_error + mov ax,dx + push dx + push ax + mov ax,# VBE_DISPI_INDEX_BANK + mov dx,# VBE_DISPI_IOPORT_INDEX + out dx,ax + pop ax + mov dx,# VBE_DISPI_IOPORT_DATA + out dx,ax + in ax,dx + pop dx + cmp dx,ax + jne dispi_set_bank_farcall_error + mov ax, #0x004f + retf +dispi_set_bank_farcall_get: + mov ax,# VBE_DISPI_INDEX_BANK + mov dx,# VBE_DISPI_IOPORT_INDEX + out dx,ax + mov dx,# VBE_DISPI_IOPORT_DATA + in ax,dx + mov dx,ax + retf +dispi_set_bank_farcall_error: + mov ax,#0x014F + retf +ASM_END +} + +ASM_START +dispi_set_x_offset: + push dx + push ax + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_X_OFFSET + out dx, ax + pop ax + mov dx, # VBE_DISPI_IOPORT_DATA + out dx, ax + pop dx + ret + +dispi_get_x_offset: + push dx + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_X_OFFSET + out dx, ax + mov dx, # VBE_DISPI_IOPORT_DATA + in ax, dx + pop dx + ret + +dispi_set_y_offset: + push dx + push ax + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_Y_OFFSET + out dx, ax + pop ax + mov dx, # VBE_DISPI_IOPORT_DATA + out dx, ax + pop dx + ret + +dispi_get_y_offset: + push dx + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_Y_OFFSET + out dx, ax + mov dx, # VBE_DISPI_IOPORT_DATA + in ax, dx + pop dx + ret + +vga_set_virt_width: + push ax + push bx + push dx + mov bx, ax + call dispi_get_bpp + cmp al, #0x04 + ja set_width_svga + shr bx, #1 +set_width_svga: + shr bx, #3 + mov dx, # VGAREG_VGA_CRTC_ADDRESS + mov ah, bl + mov al, #0x13 + out dx, ax + pop dx + pop bx + pop ax + ret + +dispi_set_virt_width: + call vga_set_virt_width + push dx + push ax + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH + out dx, ax + pop ax + mov dx, # VBE_DISPI_IOPORT_DATA + out dx, ax + pop dx + ret + +dispi_get_virt_width: + push dx + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH + out dx, ax + mov dx, # VBE_DISPI_IOPORT_DATA + in ax, dx + pop dx + ret + +dispi_get_virt_height: + push dx + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_VIRT_HEIGHT + out dx, ax + mov dx, # VBE_DISPI_IOPORT_DATA + in ax, dx + pop dx + ret + +_vga_compat_setup: + push ax + push dx + + ; set CRT X resolution + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_XRES + out dx, ax + mov dx, # VBE_DISPI_IOPORT_DATA + in ax, dx + push ax + mov dx, # VGAREG_VGA_CRTC_ADDRESS + mov ax, #0x0011 + out dx, ax + pop ax + push ax + shr ax, #3 + dec ax + mov ah, al + mov al, #0x01 + out dx, ax + pop ax + call vga_set_virt_width + + ; set CRT Y resolution + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_YRES + out dx, ax + mov dx, # VBE_DISPI_IOPORT_DATA + in ax, dx + dec ax + push ax + mov dx, # VGAREG_VGA_CRTC_ADDRESS + mov ah, al + mov al, #0x12 + out dx, ax + pop ax + mov al, #0x07 + out dx, al + inc dx + in al, dx + and al, #0xbd + test ah, #0x01 + jz bit8_clear + or al, #0x02 +bit8_clear: + test ah, #0x02 + jz bit9_clear + or al, #0x40 +bit9_clear: + out dx, al + + ; other settings + mov dx, # VGAREG_VGA_CRTC_ADDRESS + mov ax, #0x0009 + out dx, ax + mov al, #0x17 + out dx, al + mov dx, # VGAREG_VGA_CRTC_DATA + in al, dx + or al, #0x03 + out dx, al + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov dx, # VGAREG_ACTL_ADDRESS + mov al, #0x10 + out dx, al + mov dx, # VGAREG_ACTL_READ_DATA + in al, dx + or al, #0x01 + mov dx, # VGAREG_ACTL_ADDRESS + out dx, al + mov al, #0x20 + out dx, al + mov dx, # VGAREG_GRDC_ADDRESS + mov ax, #0x0506 + out dx, ax + mov dx, # VGAREG_SEQU_ADDRESS + mov ax, #0x0f02 + out dx, ax + + ; settings for >= 8bpp + mov dx, # VBE_DISPI_IOPORT_INDEX + mov ax, # VBE_DISPI_INDEX_BPP + out dx, ax + mov dx, # VBE_DISPI_IOPORT_DATA + in ax, dx + cmp al, #0x08 + jb vga_compat_end + mov dx, # VGAREG_VGA_CRTC_ADDRESS + mov al, #0x14 + out dx, al + mov dx, # VGAREG_VGA_CRTC_DATA + in al, dx + or al, #0x40 + out dx, al + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov dx, # VGAREG_ACTL_ADDRESS + mov al, #0x10 + out dx, al + mov dx, # VGAREG_ACTL_READ_DATA + in al, dx + or al, #0x40 + mov dx, # VGAREG_ACTL_ADDRESS + out dx, al + mov al, #0x20 + out dx, al + mov dx, # VGAREG_SEQU_ADDRESS + mov al, #0x04 + out dx, al + mov dx, # VGAREG_SEQU_DATA + in al, dx + or al, #0x08 + out dx, al + mov dx, # VGAREG_GRDC_ADDRESS + mov al, #0x05 + out dx, al + mov dx, # VGAREG_GRDC_DATA + in al, dx + and al, #0x9f + or al, #0x40 + out dx, al + +vga_compat_end: + pop dx + pop ax +ASM_END + + +// ModeInfo helper function +static ModeInfoListItem* mode_info_find_mode(mode, using_lfb) + Bit16u mode; Boolean using_lfb; +{ + ModeInfoListItem *cur_info=&mode_info_list; + + while (cur_info->mode != VBE_VESA_MODE_END_OF_LIST) + { + if (cur_info->mode == mode) + { + if (!using_lfb) + { + return cur_info; + } + else if (cur_info->info.ModeAttributes & VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE) + { + return cur_info; + } + else + { + cur_info++; + } + } + else + { + cur_info++; + } + } + + return 0; +} + +ASM_START + +; Has VBE display - Returns true if VBE display detected + +_vbe_has_vbe_display: + push ds + push bx + mov ax, # BIOSMEM_SEG + mov ds, ax + mov bx, # BIOSMEM_VBE_FLAG + mov al, [bx] + and al, #0x01 + xor ah, ah + pop bx + pop ds + ret + +; VBE Init - Initialise the Vesa Bios Extension Code +; This function does a sanity check on the host side display code interface. + +vbe_init: + mov ax, # VBE_DISPI_ID0 + call dispi_set_id + call dispi_get_id + cmp ax, # VBE_DISPI_ID0 + jne no_vbe_interface + push ds + push bx + mov ax, # BIOSMEM_SEG + mov ds, ax + mov bx, # BIOSMEM_VBE_FLAG + mov al, #0x01 + mov [bx], al + pop bx + pop ds + mov ax, # VBE_DISPI_ID5 + call dispi_set_id +no_vbe_interface: +#if defined(USE_BX_INFO) || defined(DEBUG) + mov bx, #msg_vbe_init + push bx + call _printf + inc sp + inc sp +#endif + ret + +; VBE Display Info - Display information on screen about the VBE + +vbe_display_info: + call _vbe_has_vbe_display + test ax, ax + jz no_vbe_flag + mov ax, #0xc000 + mov ds, ax + mov si, #_vbebios_info_string + jmp _display_string +no_vbe_flag: + mov ax, #0xc000 + mov ds, ax + mov si, #_no_vbebios_info_string + jmp _display_string + +; helper function for memory size calculation + +lmulul: + and eax, #0x0000FFFF + shl ebx, #16 + or eax, ebx + SEG SS + mul eax, dword ptr [di] + mov ebx, eax + shr ebx, #16 + ret +ASM_END + +/** Function 00h - Return VBE Controller Information + * + * Input: + * AX = 4F00h + * ES:DI = Pointer to buffer in which to place VbeInfoBlock structure + * (VbeSignature should be VBE2 when VBE 2.0 information is desired and + * the info block is 512 bytes in size) + * Output: + * AX = VBE Return Status + * + */ +void vbe_biosfn_return_controller_information(AX, ES, DI) +Bit16u *AX;Bit16u ES;Bit16u DI; +{ + Bit16u ss=get_SS(); + VbeInfoBlock vbe_info_block; + Bit16u status; + Bit16u result; + Bit16u vbe2_info; + Bit16u cur_mode=0; + Bit16u cur_ptr=34; + Bit16u size_64k; + ModeInfoListItem *cur_info=&mode_info_list; + + status = read_word(ss, AX); + +#ifdef DEBUG + printf("VBE vbe_biosfn_return_vbe_info ES%x DI%x AX%x\n",ES,DI,status); +#endif + + vbe2_info = 0; +#ifdef VBE2_NO_VESA_CHECK +#else + // get vbe_info_block into local variable + memcpyb(ss, &vbe_info_block, ES, DI, sizeof(vbe_info_block)); + + // check for VBE2 signature + if (((vbe_info_block.VbeSignature[0] == 'V') && + (vbe_info_block.VbeSignature[1] == 'B') && + (vbe_info_block.VbeSignature[2] == 'E') && + (vbe_info_block.VbeSignature[3] == '2')) || + + ((vbe_info_block.VbeSignature[0] == 'V') && + (vbe_info_block.VbeSignature[1] == 'E') && + (vbe_info_block.VbeSignature[2] == 'S') && + (vbe_info_block.VbeSignature[3] == 'A')) ) + { + vbe2_info = 1; +#ifdef DEBUG + printf("VBE correct VESA/VBE2 signature found\n"); +#endif + } +#endif + + // VBE Signature + vbe_info_block.VbeSignature[0] = 'V'; + vbe_info_block.VbeSignature[1] = 'E'; + vbe_info_block.VbeSignature[2] = 'S'; + vbe_info_block.VbeSignature[3] = 'A'; + + // VBE Version supported + vbe_info_block.VbeVersion = 0x0200; + + // OEM String + vbe_info_block.OemStringPtr_Seg = 0xc000; + vbe_info_block.OemStringPtr_Off = &vbebios_copyright; + + // Capabilities + vbe_info_block.Capabilities[0] = VBE_CAPABILITY_8BIT_DAC; + vbe_info_block.Capabilities[1] = 0; + vbe_info_block.Capabilities[2] = 0; + vbe_info_block.Capabilities[3] = 0; + + // VBE Video Mode Pointer (dynamicly generated from the mode_info_list) + vbe_info_block.VideoModePtr_Seg= ES ; + vbe_info_block.VideoModePtr_Off= DI + 34; + + // VBE Total Memory (in 64k blocks) + outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIDEO_MEMORY_64K); + vbe_info_block.TotalMemory = inw(VBE_DISPI_IOPORT_DATA); + + if (vbe2_info) + { + // OEM Stuff + vbe_info_block.OemSoftwareRev = VBE_OEM_SOFTWARE_REV; + vbe_info_block.OemVendorNamePtr_Seg = 0xc000; + vbe_info_block.OemVendorNamePtr_Off = &vbebios_vendor_name; + vbe_info_block.OemProductNamePtr_Seg = 0xc000; + vbe_info_block.OemProductNamePtr_Off = &vbebios_product_name; + vbe_info_block.OemProductRevPtr_Seg = 0xc000; + vbe_info_block.OemProductRevPtr_Off = &vbebios_product_revision; + + // copy updates in vbe_info_block back + memcpyb(ES, DI, ss, &vbe_info_block, sizeof(vbe_info_block)); + } + else + { + // copy updates in vbe_info_block back (VBE 1.x compatibility) + memcpyb(ES, DI, ss, &vbe_info_block, 256); + } + + do + { + size_64k = (Bit16u)((Bit32u)cur_info->info.XResolution * cur_info->info.XResolution * cur_info->info.BitsPerPixel) >> 19; + + if ((cur_info->info.XResolution <= dispi_get_max_xres()) && + (cur_info->info.BitsPerPixel <= dispi_get_max_bpp()) && + (size_64k <= vbe_info_block.TotalMemory)) { +#ifdef DEBUG + printf("VBE found mode %x => %x\n", cur_info->mode,cur_mode); +#endif + write_word(ES, DI + cur_ptr, cur_info->mode); + cur_mode++; + cur_ptr+=2; + } else { +#ifdef DEBUG + printf("VBE mode %x (xres=%x / bpp=%02x) not supported \n", cur_info->mode,cur_info->info.XResolution,cur_info->info.BitsPerPixel); +#endif + } + cur_info++; + } while (cur_info->mode != VBE_VESA_MODE_END_OF_LIST); + + // Add vesa mode list terminator + write_word(ES, DI + cur_ptr, cur_info->mode); + + result = 0x4f; + + write_word(ss, AX, result); +} + + +/** Function 01h - Return VBE Mode Information + * + * Input: + * AX = 4F01h + * CX = Mode Number + * ES:DI = Pointer to buffer in which to place ModeInfoBlock structure + * Output: + * AX = VBE Return Status + * + */ +void vbe_biosfn_return_mode_information(AX, CX, ES, DI) +Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI; +{ + Bit16u result=0x0100; + Bit16u ss=get_SS(); + ModeInfoBlock info; + ModeInfoListItem *cur_info; + Boolean using_lfb; + Bit16u lfb_addr; + +#ifdef DEBUG + printf("VBE vbe_biosfn_return_mode_information ES%x DI%x CX%x\n",ES,DI,CX); +#endif + + using_lfb=((CX & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER); + + CX = (CX & 0x1ff); + + cur_info = mode_info_find_mode(CX, using_lfb, &cur_info); + + if (cur_info != 0) + { +#ifdef DEBUG + printf("VBE found mode %x\n",CX); +#endif + memsetb(ss, &info, 0, sizeof(ModeInfoBlock)); + memcpyb(ss, &info, 0xc000, &(cur_info->info), sizeof(ModeInfoBlockCompact)); + if (using_lfb) { + info.NumberOfBanks = 1; + } + lfb_addr = pci_get_lfb_addr(0x1234); // experimental vendor + if (lfb_addr > 0) { + info.PhysBasePtr = ((Bit32u)lfb_addr << 16); + } + if (info.WinAAttributes & VBE_WINDOW_ATTRIBUTE_RELOCATABLE) { + info.WinFuncPtr = 0xC0000000UL; + *(Bit16u *)&(info.WinFuncPtr) = (Bit16u)(dispi_set_bank_farcall); + } + + result = 0x4f; + } + else + { +#ifdef DEBUG + printf("VBE *NOT* found mode %x\n",CX); +#endif + result = 0x100; + } + + if (result == 0x4f) + { + // copy updates in mode_info_block back + memcpyb(ES, DI, ss, &info, sizeof(info)); + } + + write_word(ss, AX, result); +} + +/** Function 02h - Set VBE Mode + * + * Input: + * AX = 4F02h + * BX = Desired Mode to set + * ES:DI = Pointer to CRTCInfoBlock structure + * Output: + * AX = VBE Return Status + * + */ +void vbe_biosfn_set_mode(AX, BX, ES, DI) +Bit16u *AX;Bit16u BX; Bit16u ES;Bit16u DI; +{ + Bit16u ss = get_SS(); + Bit16u result; + ModeInfoListItem *cur_info; + Boolean using_lfb; + Bit8u no_clear; + Bit8u lfb_flag; + + using_lfb=((BX & VBE_MODE_LINEAR_FRAME_BUFFER) == VBE_MODE_LINEAR_FRAME_BUFFER); + lfb_flag=using_lfb?VBE_DISPI_LFB_ENABLED:0; + no_clear=((BX & VBE_MODE_PRESERVE_DISPLAY_MEMORY) == VBE_MODE_PRESERVE_DISPLAY_MEMORY)?VBE_DISPI_NOCLEARMEM:0; + + BX = (BX & 0x1ff); + + //result=read_word(ss,AX); + + // check for non vesa mode + if (BX<VBE_MODE_VESA_DEFINED) + { + Bit8u mode; + + dispi_set_enable(VBE_DISPI_DISABLED); + // call the vgabios in order to set the video mode + // this allows for going back to textmode with a VBE call (some applications expect that to work) + + mode=(BX & 0xff); + biosfn_set_video_mode(mode); + result = 0x4f; + } + + cur_info = mode_info_find_mode(BX, using_lfb, &cur_info); + + if (cur_info != 0) + { +#ifdef DEBUG + printf("VBE found mode %x, setting:\n", BX); + printf("\txres%x yres%x bpp%x\n", + cur_info->info.XResolution, + cur_info->info.YResolution, + cur_info->info.BitsPerPixel); +#endif + + // first disable current mode (when switching between vesa modi) + dispi_set_enable(VBE_DISPI_DISABLED); + + if (cur_info->info.BitsPerPixel == 4) + { + biosfn_set_video_mode(0x6a); + } + + if (cur_info->info.BitsPerPixel == 8) + { + load_dac_palette(3); + } + + dispi_set_bpp(cur_info->info.BitsPerPixel); + dispi_set_xres(cur_info->info.XResolution); + dispi_set_yres(cur_info->info.YResolution); + dispi_set_bank(0); + dispi_set_enable(VBE_DISPI_ENABLED | no_clear | lfb_flag); + vga_compat_setup(); + + write_word(BIOSMEM_SEG,BIOSMEM_VBE_MODE,BX); + write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60 | no_clear)); + + result = 0x4f; + } + else + { +#ifdef DEBUG + printf("VBE *NOT* found mode %x\n" , BX); +#endif + result = 0x100; + + // FIXME: redirect non VBE modi to normal VGA bios operation + // (switch back to VGA mode + if (BX == 3) + result = 0x4f; + } + + write_word(ss, AX, result); +} + +/** Function 03h - Return Current VBE Mode + * + * Input: + * AX = 4F03h + * Output: + * AX = VBE Return Status + * BX = Current VBE Mode + * + */ +ASM_START +vbe_biosfn_return_current_mode: + push ds + mov ax, # BIOSMEM_SEG + mov ds, ax + call dispi_get_enable + and ax, # VBE_DISPI_ENABLED + jz no_vbe_mode + mov bx, # BIOSMEM_VBE_MODE + mov ax, [bx] + mov bx, ax + jnz vbe_03_ok +no_vbe_mode: + mov bx, # BIOSMEM_CURRENT_MODE + mov al, [bx] + mov bl, al + xor bh, bh +vbe_03_ok: + mov ax, #0x004f + pop ds + ret +ASM_END + + +Bit16u vbe_biosfn_read_video_state_size() +{ + return 9 * 2; +} + +void vbe_biosfn_save_video_state(ES, BX) + Bit16u ES; Bit16u BX; +{ + Bit16u enable, i; + + outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE); + enable = inw(VBE_DISPI_IOPORT_DATA); + write_word(ES, BX, enable); + BX += 2; + if (!(enable & VBE_DISPI_ENABLED)) + return; + for(i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) { + if (i != VBE_DISPI_INDEX_ENABLE) { + outw(VBE_DISPI_IOPORT_INDEX, i); + write_word(ES, BX, inw(VBE_DISPI_IOPORT_DATA)); + BX += 2; + } + } +} + + +void vbe_biosfn_restore_video_state(ES, BX) + Bit16u ES; Bit16u BX; +{ + Bit16u enable, i; + + enable = read_word(ES, BX); + BX += 2; + + if (!(enable & VBE_DISPI_ENABLED)) { + outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE); + outw(VBE_DISPI_IOPORT_DATA, enable); + } else { + outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES); + outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); + BX += 2; + outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES); + outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); + BX += 2; + outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP); + outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); + BX += 2; + outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE); + outw(VBE_DISPI_IOPORT_DATA, enable); + + for(i = VBE_DISPI_INDEX_BANK; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) { + outw(VBE_DISPI_IOPORT_INDEX, i); + outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); + BX += 2; + } + } +} + +/** Function 04h - Save/Restore State + * + * Input: + * AX = 4F04h + * DL = 00h Return Save/Restore State buffer size + * 01h Save State + * 02h Restore State + * CX = Requested states + * ES:BX = Pointer to buffer (if DL <> 00h) + * Output: + * AX = VBE Return Status + * BX = Number of 64-byte blocks to hold the state buffer (if DL=00h) + * + */ +void vbe_biosfn_save_restore_state(AX, CX, DX, ES, BX) +Bit16u *AX; Bit16u CX; Bit16u DX; Bit16u ES; Bit16u *BX; +{ + Bit16u ss=get_SS(); + Bit16u result, val; + + result = 0x4f; + switch(GET_DL()) { + case 0x00: + val = biosfn_read_video_state_size2(CX); +#ifdef DEBUG + printf("VGA state size=%x\n", val); +#endif + if (CX & 8) + val += vbe_biosfn_read_video_state_size(); + write_word(ss, BX, val); + break; + case 0x01: + val = read_word(ss, BX); + val = biosfn_save_video_state(CX, ES, val); +#ifdef DEBUG + printf("VGA save_state offset=%x\n", val); +#endif + if (CX & 8) + vbe_biosfn_save_video_state(ES, val); + break; + case 0x02: + val = read_word(ss, BX); + val = biosfn_restore_video_state(CX, ES, val); +#ifdef DEBUG + printf("VGA restore_state offset=%x\n", val); +#endif + if (CX & 8) + vbe_biosfn_restore_video_state(ES, val); + break; + default: + // function failed + result = 0x100; + break; + } + write_word(ss, AX, result); +} + +/** Function 05h - Display Window Control + * + * Input: + * AX = 4F05h + * (16-bit) BH = 00h Set memory window + * = 01h Get memory window + * BL = Window number + * = 00h Window A + * = 01h Window B + * DX = Window number in video memory in window + * granularity units (Set Memory Window only) + * Note: + * If this function is called while in a linear frame buffer mode, + * this function must fail with completion code AH=03h + * + * Output: + * AX = VBE Return Status + * DX = Window number in window granularity units + * (Get Memory Window only) + */ +ASM_START +vbe_biosfn_display_window_control: + cmp bl, #0x00 + jne vbe_05_failed + cmp bh, #0x01 + je get_display_window + jb set_display_window + mov ax, #0x0100 + ret +set_display_window: + mov ax, dx + call _dispi_set_bank + call dispi_get_bank + cmp ax, dx + jne vbe_05_failed + mov ax, #0x004f + ret +get_display_window: + call dispi_get_bank + mov dx, ax + mov ax, #0x004f + ret +vbe_05_failed: + mov ax, #0x014f + ret +ASM_END + + +/** Function 06h - Set/Get Logical Scan Line Length + * + * Input: + * AX = 4F06h + * BL = 00h Set Scan Line Length in Pixels + * = 01h Get Scan Line Length + * = 02h Set Scan Line Length in Bytes + * = 03h Get Maximum Scan Line Length + * CX = If BL=00h Desired Width in Pixels + * If BL=02h Desired Width in Bytes + * (Ignored for Get Functions) + * + * Output: + * AX = VBE Return Status + * BX = Bytes Per Scan Line + * CX = Actual Pixels Per Scan Line + * (truncated to nearest complete pixel) + * DX = Maximum Number of Scan Lines + */ +ASM_START +vbe_biosfn_set_get_logical_scan_line_length: + mov ax, cx + cmp bl, #0x01 + je get_logical_scan_line_length + cmp bl, #0x02 + je set_logical_scan_line_bytes + jb set_logical_scan_line_pixels + mov ax, #0x0100 + ret +set_logical_scan_line_bytes: + push ax + call dispi_get_bpp + xor bh, bh + mov bl, ah + or bl, bl + jnz no_4bpp_1 + shl ax, #3 + mov bl, #1 +no_4bpp_1: + xor dx, dx + pop ax + div bx +set_logical_scan_line_pixels: + call dispi_set_virt_width +get_logical_scan_line_length: + call dispi_get_bpp + xor bh, bh + mov bl, ah + call dispi_get_virt_width + mov cx, ax + or bl, bl + jnz no_4bpp_2 + shr ax, #3 + mov bl, #1 +no_4bpp_2: + mul bx + mov bx, ax + call dispi_get_virt_height + mov dx, ax + mov ax, #0x004f + ret +ASM_END + + +/** Function 07h - Set/Get Display Start + * + * Input(16-bit): + * AX = 4F07h + * BH = 00h Reserved and must be 00h + * BL = 00h Set Display Start + * = 01h Get Display Start + * = 02h Schedule Display Start (Alternate) + * = 03h Schedule Stereoscopic Display Start + * = 04h Get Scheduled Display Start Status + * = 05h Enable Stereoscopic Mode + * = 06h Disable Stereoscopic Mode + * = 80h Set Display Start during Vertical Retrace + * = 82h Set Display Start during Vertical Retrace (Alternate) + * = 83h Set Stereoscopic Display Start during Vertical Retrace + * ECX = If BL=02h/82h Display Start Address in bytes + * If BL=03h/83h Left Image Start Address in bytes + * EDX = If BL=03h/83h Right Image Start Address in bytes + * CX = If BL=00h/80h First Displayed Pixel In Scan Line + * DX = If BL=00h/80h First Displayed Scan Line + * + * Output: + * AX = VBE Return Status + * BH = If BL=01h Reserved and will be 0 + * CX = If BL=01h First Displayed Pixel In Scan Line + * If BL=04h 0 if flip has not occurred, not 0 if it has + * DX = If BL=01h First Displayed Scan Line + * + * Input(32-bit): + * BH = 00h Reserved and must be 00h + * BL = 00h Set Display Start + * = 80h Set Display Start during Vertical Retrace + * CX = Bits 0-15 of display start address + * DX = Bits 16-31 of display start address + * ES = Selector for memory mapped registers + */ +ASM_START +vbe_biosfn_set_get_display_start: + cmp bl, #0x80 + je set_display_start + cmp bl, #0x01 + je get_display_start + jb set_display_start + mov ax, #0x0100 + ret +set_display_start: + mov ax, cx + call dispi_set_x_offset + mov ax, dx + call dispi_set_y_offset + mov ax, #0x004f + ret +get_display_start: + call dispi_get_x_offset + mov cx, ax + call dispi_get_y_offset + mov dx, ax + xor bh, bh + mov ax, #0x004f + ret +ASM_END + + +/** Function 08h - Set/Get Dac Palette Format + * + * Input: + * AX = 4F08h + * BL = 00h set DAC palette width + * = 01h get DAC palette width + * BH = If BL=00h: desired number of bits per primary color + * Output: + * AX = VBE Return Status + * BH = current number of bits per primary color (06h = standard VGA) + */ +ASM_START +vbe_biosfn_set_get_dac_palette_format: + cmp bl, #0x01 + je get_dac_palette_format + jb set_dac_palette_format + mov ax, #0x0100 + ret +set_dac_palette_format: + call dispi_get_enable + cmp bh, #0x06 + je set_normal_dac + cmp bh, #0x08 + jne vbe_08_unsupported + or ax, # VBE_DISPI_8BIT_DAC + jnz set_dac_mode +set_normal_dac: + and ax, #~ VBE_DISPI_8BIT_DAC +set_dac_mode: + call _dispi_set_enable +get_dac_palette_format: + mov bh, #0x06 + call dispi_get_enable + and ax, # VBE_DISPI_8BIT_DAC + jz vbe_08_ok + mov bh, #0x08 +vbe_08_ok: + mov ax, #0x004f + ret +vbe_08_unsupported: + mov ax, #0x014f + ret +ASM_END + + +/** Function 09h - Set/Get Palette Data + * + * Input: + * AX = 4F09h + * Output: + * AX = VBE Return Status + * + * FIXME: incomplete API description, Input & Output + */ +void vbe_biosfn_set_get_palette_data(AX) +{ +} + +/** Function 0Ah - Return VBE Protected Mode Interface + * Input: AX = 4F0Ah VBE 2.0 Protected Mode Interface + * BL = 00h Return protected mode table + * + * + * Output: AX = Status + * ES = Real Mode Segment of Table + * DI = Offset of Table + * CX = Length of Table including protected mode code + * (for copying purposes) + */ +ASM_START +vbe_biosfn_return_protected_mode_interface: + test bl, bl + jnz _fail + mov di, #0xc000 + mov es, di + mov di, # vesa_pm_start + mov cx, # vesa_pm_end + sub cx, di + mov ax, #0x004f + ret +_fail: + mov ax, #0x014f + ret +ASM_END @@ -0,0 +1,315 @@ +#ifndef vbe_h_included +#define vbe_h_included + +#include "vgabios.h" + +// DISPI helper function +void dispi_set_enable(enable); + +/** VBE int10 API + * + * See the function descriptions in vbe.c for more information + */ +Boolean vbe_has_vbe_display(); +void vbe_biosfn_return_controller_information(AX, ES, DI); +void vbe_biosfn_return_mode_information(AX, CX, ES, DI); +void vbe_biosfn_set_mode(AX, BX, ES, DI); +void vbe_biosfn_save_restore_state(AX, CX, DX, ES, BX); +void vbe_biosfn_set_get_palette_data(AX); +void vbe_biosfn_return_protected_mode_interface(AX); + +// The official VBE Information Block +typedef struct VbeInfoBlock +{ + Bit8u VbeSignature[4]; + Bit16u VbeVersion; + Bit16u OemStringPtr_Off; + Bit16u OemStringPtr_Seg; + Bit8u Capabilities[4]; + Bit16u VideoModePtr_Off; + Bit16u VideoModePtr_Seg; + Bit16u TotalMemory; + Bit16u OemSoftwareRev; + Bit16u OemVendorNamePtr_Off; + Bit16u OemVendorNamePtr_Seg; + Bit16u OemProductNamePtr_Off; + Bit16u OemProductNamePtr_Seg; + Bit16u OemProductRevPtr_Off; + Bit16u OemProductRevPtr_Seg; + Bit16u Reserved[111]; // used for dynamicly generated mode list + Bit8u OemData[256]; +} VbeInfoBlock; + + +// This one is for compactly storing a static list of mode info blocks +// this saves us 189 bytes per block +typedef struct ModeInfoBlockCompact +{ +// Mandatory information for all VBE revisions + Bit16u ModeAttributes; + Bit8u WinAAttributes; + Bit8u WinBAttributes; + Bit16u WinGranularity; + Bit16u WinSize; + Bit16u WinASegment; + Bit16u WinBSegment; + Bit32u WinFuncPtr; + Bit16u BytesPerScanLine; +// Mandatory information for VBE 1.2 and above + Bit16u XResolution; + Bit16u YResolution; + Bit8u XCharSize; + Bit8u YCharSize; + Bit8u NumberOfPlanes; + Bit8u BitsPerPixel; + Bit8u NumberOfBanks; + Bit8u MemoryModel; + Bit8u BankSize; + Bit8u NumberOfImagePages; + Bit8u Reserved_page; +// Direct Color fields (required for direct/6 and YUV/7 memory models) + Bit8u RedMaskSize; + Bit8u RedFieldPosition; + Bit8u GreenMaskSize; + Bit8u GreenFieldPosition; + Bit8u BlueMaskSize; + Bit8u BlueFieldPosition; + Bit8u RsvdMaskSize; + Bit8u RsvdFieldPosition; + Bit8u DirectColorModeInfo; +// Mandatory information for VBE 2.0 and above + Bit32u PhysBasePtr; + Bit32u OffScreenMemOffset; + Bit16u OffScreenMemSize; +// Mandatory information for VBE 3.0 and above + Bit16u LinBytesPerScanLine; + Bit8u BnkNumberOfPages; + Bit8u LinNumberOfPages; + Bit8u LinRedMaskSize; + Bit8u LinRedFieldPosition; + Bit8u LinGreenMaskSize; + Bit8u LinGreenFieldPosition; + Bit8u LinBlueMaskSize; + Bit8u LinBlueFieldPosition; + Bit8u LinRsvdMaskSize; + Bit8u LinRsvdFieldPosition; + Bit32u MaxPixelClock; +// Bit8u Reserved[189]; // DO NOT PUT THIS IN HERE because of Compact Mode Info storage in bios +} ModeInfoBlockCompact; + +typedef struct ModeInfoBlock +{ +// Mandatory information for all VBE revisions + Bit16u ModeAttributes; + Bit8u WinAAttributes; + Bit8u WinBAttributes; + Bit16u WinGranularity; + Bit16u WinSize; + Bit16u WinASegment; + Bit16u WinBSegment; + Bit32u WinFuncPtr; + Bit16u BytesPerScanLine; +// Mandatory information for VBE 1.2 and above + Bit16u XResolution; + Bit16u YResolution; + Bit8u XCharSize; + Bit8u YCharSize; + Bit8u NumberOfPlanes; + Bit8u BitsPerPixel; + Bit8u NumberOfBanks; + Bit8u MemoryModel; + Bit8u BankSize; + Bit8u NumberOfImagePages; + Bit8u Reserved_page; +// Direct Color fields (required for direct/6 and YUV/7 memory models) + Bit8u RedMaskSize; + Bit8u RedFieldPosition; + Bit8u GreenMaskSize; + Bit8u GreenFieldPosition; + Bit8u BlueMaskSize; + Bit8u BlueFieldPosition; + Bit8u RsvdMaskSize; + Bit8u RsvdFieldPosition; + Bit8u DirectColorModeInfo; +// Mandatory information for VBE 2.0 and above + Bit32u PhysBasePtr; + Bit32u OffScreenMemOffset; + Bit16u OffScreenMemSize; +// Mandatory information for VBE 3.0 and above + Bit16u LinBytesPerScanLine; + Bit8u BnkNumberOfPages; + Bit8u LinNumberOfPages; + Bit8u LinRedMaskSize; + Bit8u LinRedFieldPosition; + Bit8u LinGreenMaskSize; + Bit8u LinGreenFieldPosition; + Bit8u LinBlueMaskSize; + Bit8u LinBlueFieldPosition; + Bit8u LinRsvdMaskSize; + Bit8u LinRsvdFieldPosition; + Bit32u MaxPixelClock; + Bit8u Reserved[189]; +} ModeInfoBlock; + +typedef struct ModeInfoListItem +{ + Bit16u mode; + ModeInfoBlockCompact info; +} ModeInfoListItem; + +// VBE Return Status Info +// AL +#define VBE_RETURN_STATUS_SUPPORTED 0x4F +#define VBE_RETURN_STATUS_UNSUPPORTED 0x00 +// AH +#define VBE_RETURN_STATUS_SUCCESSFULL 0x00 +#define VBE_RETURN_STATUS_FAILED 0x01 +#define VBE_RETURN_STATUS_NOT_SUPPORTED 0x02 +#define VBE_RETURN_STATUS_INVALID 0x03 + +// VBE Mode Numbers + +#define VBE_MODE_VESA_DEFINED 0x0100 +#define VBE_MODE_REFRESH_RATE_USE_CRTC 0x0800 +#define VBE_MODE_LINEAR_FRAME_BUFFER 0x4000 +#define VBE_MODE_PRESERVE_DISPLAY_MEMORY 0x8000 + +// VBE GFX Mode Number + +#define VBE_VESA_MODE_640X400X8 0x100 +#define VBE_VESA_MODE_640X480X8 0x101 +#define VBE_VESA_MODE_800X600X4 0x102 +#define VBE_VESA_MODE_800X600X8 0x103 +#define VBE_VESA_MODE_1024X768X4 0x104 +#define VBE_VESA_MODE_1024X768X8 0x105 +#define VBE_VESA_MODE_1280X1024X4 0x106 +#define VBE_VESA_MODE_1280X1024X8 0x107 +#define VBE_VESA_MODE_320X200X1555 0x10D +#define VBE_VESA_MODE_320X200X565 0x10E +#define VBE_VESA_MODE_320X200X888 0x10F +#define VBE_VESA_MODE_640X480X1555 0x110 +#define VBE_VESA_MODE_640X480X565 0x111 +#define VBE_VESA_MODE_640X480X888 0x112 +#define VBE_VESA_MODE_800X600X1555 0x113 +#define VBE_VESA_MODE_800X600X565 0x114 +#define VBE_VESA_MODE_800X600X888 0x115 +#define VBE_VESA_MODE_1024X768X1555 0x116 +#define VBE_VESA_MODE_1024X768X565 0x117 +#define VBE_VESA_MODE_1024X768X888 0x118 +#define VBE_VESA_MODE_1280X1024X1555 0x119 +#define VBE_VESA_MODE_1280X1024X565 0x11A +#define VBE_VESA_MODE_1280X1024X888 0x11B +#define VBE_VESA_MODE_1600X1200X8 0x11C +#define VBE_VESA_MODE_1600X1200X1555 0x11D +#define VBE_VESA_MODE_1600X1200X565 0x11E +#define VBE_VESA_MODE_1600X1200X888 0x11F + +// BOCHS/PLEX86 'own' mode numbers +#define VBE_OWN_MODE_320X200X8888 0x140 +#define VBE_OWN_MODE_640X400X8888 0x141 +#define VBE_OWN_MODE_640X480X8888 0x142 +#define VBE_OWN_MODE_800X600X8888 0x143 +#define VBE_OWN_MODE_1024X768X8888 0x144 +#define VBE_OWN_MODE_1280X1024X8888 0x145 +#define VBE_OWN_MODE_320X200X8 0x146 +#define VBE_OWN_MODE_1600X1200X8888 0x147 +#define VBE_OWN_MODE_1152X864X8 0x148 +#define VBE_OWN_MODE_1152X864X1555 0x149 +#define VBE_OWN_MODE_1152X864X565 0x14a +#define VBE_OWN_MODE_1152X864X888 0x14b +#define VBE_OWN_MODE_1152X864X8888 0x14c + +#define VBE_VESA_MODE_END_OF_LIST 0xFFFF + +// Capabilities + +#define VBE_CAPABILITY_8BIT_DAC 0x0001 +#define VBE_CAPABILITY_NOT_VGA_COMPATIBLE 0x0002 +#define VBE_CAPABILITY_RAMDAC_USE_BLANK_BIT 0x0004 +#define VBE_CAPABILITY_STEREOSCOPIC_SUPPORT 0x0008 +#define VBE_CAPABILITY_STEREO_VIA_VESA_EVC 0x0010 + +// Mode Attributes + +#define VBE_MODE_ATTRIBUTE_SUPPORTED 0x0001 +#define VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE 0x0002 +#define VBE_MODE_ATTRIBUTE_TTY_BIOS_SUPPORT 0x0004 +#define VBE_MODE_ATTRIBUTE_COLOR_MODE 0x0008 +#define VBE_MODE_ATTRIBUTE_GRAPHICS_MODE 0x0010 +#define VBE_MODE_ATTRIBUTE_NOT_VGA_COMPATIBLE 0x0020 +#define VBE_MODE_ATTRIBUTE_NO_VGA_COMPATIBLE_WINDOW 0x0040 +#define VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE 0x0080 +#define VBE_MODE_ATTRIBUTE_DOUBLE_SCAN_MODE 0x0100 +#define VBE_MODE_ATTRIBUTE_INTERLACE_MODE 0x0200 +#define VBE_MODE_ATTRIBUTE_HARDWARE_TRIPLE_BUFFER 0x0400 +#define VBE_MODE_ATTRIBUTE_HARDWARE_STEREOSCOPIC_DISPLAY 0x0800 +#define VBE_MODE_ATTRIBUTE_DUAL_DISPLAY_START_ADDRESS 0x1000 + +#define VBE_MODE_ATTTRIBUTE_LFB_ONLY ( VBE_MODE_ATTRIBUTE_NO_VGA_COMPATIBLE_WINDOW | VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE ) + +// Window attributes + +#define VBE_WINDOW_ATTRIBUTE_RELOCATABLE 0x01 +#define VBE_WINDOW_ATTRIBUTE_READABLE 0x02 +#define VBE_WINDOW_ATTRIBUTE_WRITEABLE 0x04 + +// Memory model + +#define VBE_MEMORYMODEL_TEXT_MODE 0x00 +#define VBE_MEMORYMODEL_CGA_GRAPHICS 0x01 +#define VBE_MEMORYMODEL_HERCULES_GRAPHICS 0x02 +#define VBE_MEMORYMODEL_PLANAR 0x03 +#define VBE_MEMORYMODEL_PACKED_PIXEL 0x04 +#define VBE_MEMORYMODEL_NON_CHAIN_4_256 0x05 +#define VBE_MEMORYMODEL_DIRECT_COLOR 0x06 +#define VBE_MEMORYMODEL_YUV 0x07 + +// DirectColorModeInfo + +#define VBE_DIRECTCOLOR_COLOR_RAMP_PROGRAMMABLE 0x01 +#define VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE 0x02 + +// GUEST <-> HOST Communication API + +// FIXME: either dynamicly ask host for this or put somewhere high in physical memory +// like 0xE0000000 + + + #define VBE_DISPI_BANK_ADDRESS 0xA0000 + #define VBE_DISPI_BANK_SIZE_KB 64 + + #define VBE_DISPI_MAX_XRES 2560 + #define VBE_DISPI_MAX_YRES 1600 + + #define VBE_DISPI_IOPORT_INDEX 0x01CE + #define VBE_DISPI_IOPORT_DATA 0x01CF + + #define VBE_DISPI_INDEX_ID 0x0 + #define VBE_DISPI_INDEX_XRES 0x1 + #define VBE_DISPI_INDEX_YRES 0x2 + #define VBE_DISPI_INDEX_BPP 0x3 + #define VBE_DISPI_INDEX_ENABLE 0x4 + #define VBE_DISPI_INDEX_BANK 0x5 + #define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 + #define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 + #define VBE_DISPI_INDEX_X_OFFSET 0x8 + #define VBE_DISPI_INDEX_Y_OFFSET 0x9 + #define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa + + #define VBE_DISPI_ID0 0xB0C0 + #define VBE_DISPI_ID1 0xB0C1 + #define VBE_DISPI_ID2 0xB0C2 + #define VBE_DISPI_ID3 0xB0C3 + #define VBE_DISPI_ID4 0xB0C4 + #define VBE_DISPI_ID5 0xB0C5 + + #define VBE_DISPI_DISABLED 0x00 + #define VBE_DISPI_ENABLED 0x01 + #define VBE_DISPI_GETCAPS 0x02 + #define VBE_DISPI_8BIT_DAC 0x20 + #define VBE_DISPI_LFB_ENABLED 0x40 + #define VBE_DISPI_NOCLEARMEM 0x80 + + #define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000 + +#endif diff --git a/vbe_display_api.txt b/vbe_display_api.txt new file mode 100644 index 0000000..fddb78b --- /dev/null +++ b/vbe_display_api.txt @@ -0,0 +1,237 @@ +VBE Display API +------------------------------------------------------------------------------------------------------------- + This document is part of the Bochs/VBEBios documentation, + it specifies the bochs host <-> vbebios client communication. + + That means, the display code implementation and the vbebios code depend + very heavily on each other. As such, this documents needs be synchronised + between bochs CVS and the vgabios CVS. + + This document does not describe how the VBEBios implements the VBE2/3 spec. + This document does not describe how the Bochs display code will display gfx based upon this spec. + + +API History +----------- +0xb0c0 supports the following VBE_DISPI_ interfaces (present in Bochs 1.4): + VBE_DISPI_INDEX_ID + VBE_DISPI_INDEX_XRES + VBE_DISPI_INDEX_YRES + VBE_DISPI_INDEX_BPP + VBE_DISPI_INDEX_ENABLE + VBE_DISPI_INDEX_BANK + + Bpp format supported is: + VBE_DISPI_BPP_8 + +0xb0c1 supports 0xb0c0 VBE_DISPI_ interfaces, additional interfaces (present in Bochs 2.0): + VBE_DISPI_INDEX_VIRT_WIDTH + VBE_DISPI_INDEX_VIRT_HEIGHT + VBE_DISPI_INDEX_X_OFFSET + VBE_DISPI_INDEX_Y_OFFSET + +0xb0c2 supports 0xb0c1 VBE_DISPI_ interfaces, interfaces updated for + additional features (present in Bochs 2.1): + VBE_DISPI_INDEX_BPP supports >8bpp color depth (value = bits) + VBE_DISPI_INDEX_ENABLE supports new flags VBE_DISPI_NOCLEARMEM and VBE_DISPI_LFB_ENABLED + VBE i/o registers changed from 0xFF80/81 to 0x01CE/CF + +0xb0c3 supports 0xb0c2 VBE_DISPI_ interfaces, interfaces updated for + additional features: + VBE_DISPI_INDEX_ENABLE supports new flags VBE_DISPI_GETCAPS and VBE_DISPI_8BIT_DAC + +0xb0c4 VBE video memory increased to 8 MB + + +History +------- + Version 0.6 2002 Nov 23 Jeroen Janssen + - Added LFB support + - Added Virt width, height and x,y offset + + Version 0.5 2002 March 08 Jeroen Janssen + - Added documentation about panic behaviour / current limits of the data values. + - Changed BPP API (in order to include future (A)RGB formats) + - Initial version (based upon extended display text of the vbe bochs display patch) + + +Todo +---- + Version 0.6+ [random order] + - Add lots of different (A)RGB formats + +References +---------- + [VBE3] VBE 3 Specification at + http://www.vesa.org/vbe3.pdf + + [BOCHS] Bochs Open Source IA-32 Emulator at + http://bochs.sourceforge.net + + [VBEBIOS] VBE Bios for Bochs at + http://savannah.gnu.org/projects/vgabios/ + + [Screenshots] Screenshots of programs using the VBE Bios at + http://japj.org/projects/bochs_plex86/screenshots.html + +Abbreviations +------------- + VBE Vesa Bios Extension + DISPI (Bochs) Display Interface + BPP Bits Per Pixel + LFB Linear Frame Buffer + + +#defines +-------- +vbetables-gen.c + #define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 8 + +vbe.h + #define VBE_DISPI_BANK_ADDRESS 0xA0000 + #define VBE_DISPI_BANK_SIZE_KB 64 + + #define VBE_DISPI_MAX_XRES 1024 + #define VBE_DISPI_MAX_YRES 768 + + #define VBE_DISPI_IOPORT_INDEX 0x01CE + #define VBE_DISPI_IOPORT_DATA 0x01CF + + #define VBE_DISPI_INDEX_ID 0x0 + #define VBE_DISPI_INDEX_XRES 0x1 + #define VBE_DISPI_INDEX_YRES 0x2 + #define VBE_DISPI_INDEX_BPP 0x3 + #define VBE_DISPI_INDEX_ENABLE 0x4 + #define VBE_DISPI_INDEX_BANK 0x5 + #define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 + #define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 + #define VBE_DISPI_INDEX_X_OFFSET 0x8 + #define VBE_DISPI_INDEX_Y_OFFSET 0x9 + + #define VBE_DISPI_ID0 0xB0C0 + #define VBE_DISPI_ID1 0xB0C1 + #define VBE_DISPI_ID2 0xB0C2 + #define VBE_DISPI_ID3 0xB0C3 + #define VBE_DISPI_ID4 0xB0C4 + + #define VBE_DISPI_DISABLED 0x00 + #define VBE_DISPI_ENABLED 0x01 + #define VBE_DISPI_VBE_ENABLED 0x40 + #define VBE_DISPI_NOCLEARMEM 0x80 + + #define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000 + +API +--- + The display api works by using a index (VBE_DISPI_IOPORT_INDEX) and + data (VBE_DISPI_IOPORT_DATA) ioport. One writes the index of the parameter to the index port. + Next, the parameter value can be read or written. + +[0xb0c0] + * VBE_DISPI_INDEX_ID : WORD {R,W} + This parameter can be used to detect the current display API (both bochs & vbebios). + The bios writes VBE_DISPI_ID0 to the dataport and reads it back again. + This way, the display code knows the vbebios 'ID' and the vbebios can check if the correct + display code is present. + As a result, a PANIC can be generated if an incompatible vbebios/display code combination is detected. + This panic can be generated from the bochs display code (NOT the bios, see Notes). + + Example values: VBE_DISPI_ID0 + + * VBE_DISPI_INDEX_XRES : WORD {R,W} + This parameter can be used to read/write the vbe display X resolution (in pixels). + It's illegal to set the XRES when the VBE is enabled (display code should generate PANIC). + + If the value written exceeds VBE_DISPI_MAX_XRES, the display code needs to generate a PANIC. + + Example values: 320,640,800,1024 + + * VBE_DISPI_INDEX_YRES : WORD {R,W} + This parameter can be used to read/write the vbe display Y resolution (in pixels). + It's illegal to set the YRES when the VBE is enabled (display code should generate PANIC). + + If the value written exceeds VBE_DISPI_MAX_YRES, the display code needs to generate a PANIC. + + Example values: 200,400,480,600,768 + + * VBE_DISPI_INDEX_BPP : WORD {R,W} + This parameter can be used to read/write the vbe display BPP. + It's illegal to set the BPP when the VBE is enabled (display code should generate PANIC). + + If the value written is an incompatible BPP, the display code needs to generate a PANIC. + + Example values: VBE_DISPI_BPP_8 + + * VBE_DISPI_INDEX_ENABLE : WORD {R,W} + This parameter can be used to read/write the vbe ENABLED state. + If the bios writes VBE_DISPI_ENABLED then the display code will setup a hostside display mode + with the current XRES, YRES and BPP settings. + If the bios write VBE_DISPI_DISABLED then the display code will switch back to normal vga mode behaviour. + + Example values: VBE_DISPI_ENABLED, VBE_DISPI_DISABLED + + * VBE_DISPI_INDEX_BANK : WORD {R,W} + This parameter can be used to read/write the current selected BANK (at 0xA0000). + This can be used for switching banks in banked mode. + +[0xb0c1] + * VBE_DISPI_INDEX_VIRT_WIDTH : WORD {R,W} + This parameter can be used to read/write the current virtual width. + Upon enabling a mode, this will be set to the current xres + Setting this field during enabled mode will result in the virtual width to be changed. + Value will be adjusted if current setting is not possible. + + * VBE_DISPI_INDEX_VIRT_HEIGHT : WORD {R} + This parameter can be read in order to obtain the current virtual height. + This setting will be adjusted after setting a virtual width in order to stay within limit of video memory. + + * VBE_DISPI_INDEX_X_OFFSET : WORD {R,W} + The current X offset (in pixels!) of the visible screen part. + Writing a new offset will also result in a complete screen refresh. + + * VBE_DISPI_INDEX_Y_OFFSET : WORD {R,W} + The current Y offset (in pixels!) of the visible screen part. + Writing a new offset will also result in a complete screen refresh. + + +[0xb0c2] + * VBE_DISPI_INDEX_BPP : WORD {R,W} + The value written is now the number of bits per pixel. A value of 0 is treated + the same as 8 for backward compatibilty. These values are supported: 8, 15, + 16, 24 and 32. The value of 4 is not yet handled in the VBE code. + * VBE_DISPI_INDEX_ENABLE : WORD {R,W} + The new flag VBE_DISPI_NOCLEARMEM allows to preserve the VBE video memory. + The new flag VBE_DISPI_LFB_ENABLED indicates the usage of the LFB. + +[0xb0c3] + * VBE_DISPI_INDEX_ENABLE : WORD {R,W} + If the new flag VBE_DISPI_GETCAPS is enabled, the xres, yres and bpp registers + return the gui capabilities. + The new flag VBE_DISPI_8BIT_DAC switches the DAC to 8 bit mode. + +[0xb0c4] + * VBE_DISPI_TOTAL_VIDEO_MEMORY_MB set to 8 (moved to auto-generated vbetables.h) + +Displaying GFX (banked mode) +-------------- + What happens is that the total screen is devided in banks of 'VBE_DISPI_BANK_SIZE_KB' KiloByte in size. + If you want to set a pixel you can calculate its bank by doing: + + offset = pixel_x + pixel_y * resolution_x; + bank = offset / 64 Kb (rounded 1.9999 -> 1) + + bank_pixel_pos = offset - bank * 64Kb + + Now you can set the current bank and put the pixel at VBE_DISPI_BANK_ADDRESS + bank_pixel_pos + +Displaying GFX (linear frame buffer mode) +-------------- + NOT WRITTEN YET + +Notes +----- + * Since the XRES/YRES/BPP may not be written when VBE is enabled, if you want to switch from one VBE mode + to another, you will need to disable VBE first. + + * Note when the bios doesn't find a valid DISPI_ID, it can disable the VBE functions. This allows people to + use the same bios for both vbe enabled and disabled bochs executables. diff --git a/vbetables-gen.c b/vbetables-gen.c new file mode 100644 index 0000000..cf3965f --- /dev/null +++ b/vbetables-gen.c @@ -0,0 +1,290 @@ +/* Generate the VGABIOS VBE Tables */ +#include <stdlib.h> +#include <stdio.h> + +#define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 16 + +typedef struct { + int width; + int height; + int depth; + int mode; +} ModeInfo; + +ModeInfo modes[] = { + /* standard VESA modes */ +{ 640, 400, 8 , 0x100}, +{ 640, 480, 8 , 0x101}, +{ 800, 600, 4 , 0x102}, +{ 800, 600, 8 , 0x103}, +{ 1024, 768, 4 , 0x104}, +{ 1024, 768, 8 , 0x105}, +{ 1280, 1024, 4 , 0x106}, +{ 1280, 1024, 8 , 0x107}, +{ 320, 200, 15 , 0x10D}, +{ 320, 200, 16 , 0x10E}, +{ 320, 200, 24 , 0x10F}, +{ 640, 480, 15 , 0x110}, +{ 640, 480, 16 , 0x111}, +{ 640, 480, 24 , 0x112}, +{ 800, 600, 15 , 0x113}, +{ 800, 600, 16 , 0x114}, +{ 800, 600, 24 , 0x115}, +{ 1024, 768, 15 , 0x116}, +{ 1024, 768, 16 , 0x117}, +{ 1024, 768, 24 , 0x118}, +{ 1280, 1024, 15 , 0x119}, +{ 1280, 1024, 16 , 0x11A}, +{ 1280, 1024, 24 , 0x11B}, +{ 1600, 1200, 8 , 0x11C}, +{ 1600, 1200, 15 , 0x11D}, +{ 1600, 1200, 16 , 0x11E}, +{ 1600, 1200, 24 , 0x11F}, + + /* BOCHS/PLEX86 'own' mode numbers */ +// It is not necessary... commented out... +/* +{ 320, 200, 32 , 0x140}, +{ 640, 400, 32 , 0x141}, +{ 640, 480, 32 , 0x142}, +{ 800, 600, 32 , 0x143}, +{ 1024, 768, 32 , 0x144}, +{ 1280, 1024, 32 , 0x145}, +{ 320, 200, 8 , 0x146}, +{ 1600, 1200, 32 , 0x147}, +{ 1152, 864, 8 , 0x148}, +{ 1152, 864, 15 , 0x149}, +{ 1152, 864, 16 , 0x14a}, +{ 1152, 864, 24 , 0x14b}, +{ 1152, 864, 32 , 0x14c}, +{ 1280, 768, 16 , 0x175}, +{ 1280, 768, 24 , 0x176}, +{ 1280, 768, 32 , 0x177}, +{ 1280, 800, 16 , 0x178}, +{ 1280, 800, 24 , 0x179}, +{ 1280, 800, 32 , 0x17a}, +{ 1280, 960, 16 , 0x17b}, +{ 1280, 960, 24 , 0x17c}, +{ 1280, 960, 32 , 0x17d}, +{ 1440, 900, 16 , 0x17e}, +{ 1440, 900, 24 , 0x17f}, +{ 1440, 900, 32 , 0x180}, +{ 1400, 1050, 16 , 0x181}, +{ 1400, 1050, 24 , 0x182}, +{ 1400, 1050, 32 , 0x183}, +{ 1680, 1050, 16 , 0x184}, +{ 1680, 1050, 24 , 0x185}, +{ 1680, 1050, 32 , 0x186}, +{ 1920, 1200, 16 , 0x187}, +{ 1920, 1200, 24 , 0x188}, +{ 1920, 1200, 32 , 0x189}, +{ 2560, 1600, 16 , 0x18a}, +{ 2560, 1600, 24 , 0x18b}, +{ 2560, 1600, 32 , 0x18c}, +{ 1280, 720, 16 , 0x18d}, +{ 1280, 720, 24 , 0x18e}, +{ 1280, 720, 32 , 0x18f}, +{ 1920, 1080, 16 , 0x190}, +{ 1920, 1080, 24 , 0x191}, +{ 1920, 1080, 32 , 0x192}, +*/ + +// by caramis... for 'stdvga ext' +// add new mode for mobile... +{ 320, 480, 16 , 0x140}, +{ 320, 480, 24 , 0x141}, +{ 320, 480, 32 , 0x142}, +{ 480, 800, 16 , 0x143}, +{ 480, 800, 24 , 0x144}, +{ 480, 800, 32 , 0x145}, +{ 600, 1024, 16 , 0x146}, +{ 600, 1024, 24 , 0x147}, +{ 600, 1024, 32 , 0x148}, +{ 720, 1280, 16 , 0x149}, +{ 720, 1280, 24 , 0x14a}, +{ 720, 1280, 32 , 0x14b}, +// + +{ 0, }, +}; + +int main(int argc, char **argv) +{ + const ModeInfo *pm; + int pages, pitch; + int r_size, r_pos, g_size, g_pos, b_size, b_pos, a_size, a_pos; + const char *str; + long vram_size = VBE_DISPI_TOTAL_VIDEO_MEMORY_MB * 1024 * 1024; + + printf("/* THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT */\n\n"); + printf("#define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB %d\n\n", VBE_DISPI_TOTAL_VIDEO_MEMORY_MB); + printf("static ModeInfoListItem mode_info_list[]=\n"); + printf("{\n"); + for (pm = modes; pm->mode != 0; pm++) { + if (pm->depth == 4) + pitch = (pm->width + 7) / 8; + else + pitch = pm->width * ((pm->depth + 7) / 8); + pages = vram_size / (pm->height * pitch); + if (pages > 0) { + printf("{ 0x%04x, /* %dx%dx%d */\n", + pm->mode, pm->width, pm->height, pm->depth); + if (pm->depth == 4) + printf("{ /*Bit16u ModeAttributes*/ %s,\n", + "VBE_MODE_ATTRIBUTE_SUPPORTED | " + "VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | " + "VBE_MODE_ATTRIBUTE_COLOR_MODE | " + "VBE_MODE_ATTRIBUTE_TTY_BIOS_SUPPORT | " + "VBE_MODE_ATTRIBUTE_GRAPHICS_MODE"); + else + printf("{ /*Bit16u ModeAttributes*/ %s,\n", + "VBE_MODE_ATTRIBUTE_SUPPORTED | " + "VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | " + "VBE_MODE_ATTRIBUTE_COLOR_MODE | " + "VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE | " + "VBE_MODE_ATTRIBUTE_GRAPHICS_MODE"); + printf("/*Bit8u WinAAttributes*/ %s,\n", + "VBE_WINDOW_ATTRIBUTE_RELOCATABLE | " + "VBE_WINDOW_ATTRIBUTE_READABLE | " + "VBE_WINDOW_ATTRIBUTE_WRITEABLE"); + + printf("/*Bit8u WinBAttributes*/ %d,\n", 0); + + printf("/*Bit16u WinGranularity*/ %s,\n", "VBE_DISPI_BANK_SIZE_KB"); + + printf("/*Bit16u WinSize*/ %s,\n", "VBE_DISPI_BANK_SIZE_KB"); + + printf("/*Bit16u WinASegment*/ %s,\n", "VGAMEM_GRAPH"); + + printf("/*Bit16u WinBSegment*/ 0x%04x,\n", 0); + + printf("/*Bit32u WinFuncPtr*/ %d,\n", 0); + + printf("/*Bit16u BytesPerScanLine*/ %d,\n", pitch); + + // Mandatory information for VBE 1.2 and above + printf("/*Bit16u XResolution*/ %d,\n", pm->width); + printf("/*Bit16u YResolution*/ %d,\n", pm->height); + printf("/*Bit8u XCharSize*/ %d,\n", 8); + printf("/*Bit8u YCharSize*/ %d,\n", 16); + if (pm->depth == 4) { + printf("/*Bit8u NumberOfPlanes*/ %d,\n", 4); + } else { + printf("/*Bit8u NumberOfPlanes*/ %d,\n", 1); + } + printf("/*Bit8u BitsPerPixel*/ %d,\n", pm->depth); + printf("/*Bit8u NumberOfBanks*/ %d,\n", + (pm->height * pitch + 65535) / 65536); + + if (pm->depth == 4) + str = "VBE_MEMORYMODEL_PLANAR"; + else if (pm->depth == 8) + str = "VBE_MEMORYMODEL_PACKED_PIXEL"; + else + str = "VBE_MEMORYMODEL_DIRECT_COLOR"; + printf("/*Bit8u MemoryModel*/ %s,\n", str); + printf("/*Bit8u BankSize*/ %d,\n", 0); + if (pm->depth == 4) + printf("/*Bit8u NumberOfImagePages*/ %d,\n", (pages / 4) - 1); + else + printf("/*Bit8u NumberOfImagePages*/ %d,\n", pages - 1); + printf("/*Bit8u Reserved_page*/ %d,\n", 0); + + // Direct Color fields (required for direct/6 and YUV/7 memory models) + switch(pm->depth) { + case 15: + r_size = 5; + r_pos = 10; + g_size = 5; + g_pos = 5; + b_size = 5; + b_pos = 0; + a_size = 1; + a_pos = 15; + break; + case 16: + r_size = 5; + r_pos = 11; + g_size = 6; + g_pos = 5; + b_size = 5; + b_pos = 0; + a_size = 0; + a_pos = 0; + break; + case 24: + r_size = 8; + r_pos = 16; + g_size = 8; + g_pos = 8; + b_size = 8; + b_pos = 0; + a_size = 0; + a_pos = 0; + break; + case 32: + r_size = 8; + r_pos = 16; + g_size = 8; + g_pos = 8; + b_size = 8; + b_pos = 0; + a_size = 8; + a_pos = 24; + break; + default: + r_size = 0; + r_pos = 0; + g_size = 0; + g_pos = 0; + b_size = 0; + b_pos = 0; + a_size = 0; + a_pos = 0; + break; + } + + printf("/*Bit8u RedMaskSize*/ %d,\n", r_size); + printf("/*Bit8u RedFieldPosition*/ %d,\n", r_pos); + printf("/*Bit8u GreenMaskSize*/ %d,\n", g_size); + printf("/*Bit8u GreenFieldPosition*/ %d,\n", g_pos); + printf("/*Bit8u BlueMaskSize*/ %d,\n", b_size); + printf("/*Bit8u BlueFieldPosition*/ %d,\n", b_pos); + printf("/*Bit8u RsvdMaskSize*/ %d,\n", a_size); + printf("/*Bit8u RsvdFieldPosition*/ %d,\n", a_pos); + if (pm->depth == 32) + printf("/*Bit8u DirectColorModeInfo*/ %s,\n", + "VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE"); + else + printf("/*Bit8u DirectColorModeInfo*/ %s,\n", "0"); + +// Mandatory information for VBE 2.0 and above + if (pm->depth > 4) + printf("/*Bit32u PhysBasePtr*/ %s,\n", + "VBE_DISPI_LFB_PHYSICAL_ADDRESS"); + else + printf("/*Bit32u PhysBasePtr*/ %s,\n", "0"); + printf("/*Bit32u OffScreenMemOffset*/ %d,\n", 0); + printf("/*Bit16u OffScreenMemSize*/ %d,\n", 0); + // Mandatory information for VBE 3.0 and above + printf("/*Bit16u LinBytesPerScanLine*/ %d,\n", pitch); + printf("/*Bit8u BnkNumberOfPages*/ %d,\n", 0); + printf("/*Bit8u LinNumberOfPages*/ %d,\n", 0); + printf("/*Bit8u LinRedMaskSize*/ %d,\n", r_size); + printf("/*Bit8u LinRedFieldPosition*/ %d,\n", r_pos); + printf("/*Bit8u LinGreenMaskSize*/ %d,\n", g_size); + printf("/*Bit8u LinGreenFieldPosition*/ %d,\n", g_pos); + printf("/*Bit8u LinBlueMaskSize*/ %d,\n", b_size); + printf("/*Bit8u LinBlueFieldPosition*/ %d,\n", b_pos); + printf("/*Bit8u LinRsvdMaskSize*/ %d,\n", a_size); + printf("/*Bit8u LinRsvdFieldPosition*/ %d,\n", a_pos); + printf("/*Bit32u MaxPixelClock*/ %d,\n", 0); + printf("} },\n"); + } + } + printf("{ VBE_VESA_MODE_END_OF_LIST,\n"); + printf("{ 0,\n"); + printf("} },\n"); + printf("};\n"); + return 0; +} diff --git a/vgabios.c b/vgabios.c new file mode 100644 index 0000000..fcaa383 --- /dev/null +++ b/vgabios.c @@ -0,0 +1,3931 @@ +// ============================================================================================ +/* + * vgabios.c + */ +// ============================================================================================ +// +// Copyright (C) 2001-2008 the LGPL VGABios developers Team +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// ============================================================================================ +// +// This VGA Bios is specific to the plex86/bochs Emulated VGA card. +// You can NOT drive any physical vga card with it. +// +// ============================================================================================ +// +// This file contains code ripped from : +// - rombios.c of plex86 +// +// This VGA Bios contains fonts from : +// - fntcol16.zip (c) by Joseph Gil avalable at : +// ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip +// These fonts are public domain +// +// This VGA Bios is based on information taken from : +// - Kevin Lawton's vga card emulation for bochs/plex86 +// - Ralf Brown's interrupts list available at http://www.cs.cmu.edu/afs/cs/user/ralf/pub/WWW/files.html +// - Finn Thogersons' VGADOC4b available at http://home.worldonline.dk/~finth/ +// - Michael Abrash's Graphics Programming Black Book +// - Francois Gervais' book "programmation des cartes graphiques cga-ega-vga" edited by sybex +// - DOSEMU 1.0.1 source code for several tables values and formulas +// +// Thanks for patches, comments and ideas to : +// - techt@pikeonline.net +// +// ============================================================================================ + +#include "vgabios.h" + +#ifdef VBE +#include "vbe.h" +#endif + +#define USE_BX_INFO + +/* Declares */ +static Bit8u read_byte(); +static Bit16u read_word(); +static void write_byte(); +static void write_word(); +static Bit8u inb(); +static Bit16u inw(); +static void outb(); +static void outw(); + +static Bit16u get_SS(); + +// Output +static void printf(); +static void unimplemented(); +static void unknown(); + +static Bit8u find_vga_entry(); +static void load_dac_palette(); + +static void memsetb(); +static void memsetw(); +static void memcpyb(); +static void memcpyw(); + +static void biosfn_set_video_mode(); +static void biosfn_set_cursor_shape(); +static void biosfn_set_cursor_pos(); +static void biosfn_get_cursor_pos(); +static void biosfn_set_active_page(); +static void biosfn_scroll(); +static void biosfn_read_char_attr(); +static void biosfn_write_char_attr(); +static void biosfn_write_char_only(); +static void biosfn_write_pixel(); +static void biosfn_read_pixel(); +static void biosfn_write_teletype(); +static void biosfn_perform_gray_scale_summing(); +static void biosfn_load_text_user_pat(); +static void biosfn_load_text_8_14_pat(); +static void biosfn_load_text_8_8_pat(); +static void biosfn_load_text_8_16_pat(); +static void biosfn_load_gfx_8_8_chars(); +static void biosfn_load_gfx_user_chars(); +static void biosfn_load_gfx_8_14_chars(); +static void biosfn_load_gfx_8_8_dd_chars(); +static void biosfn_load_gfx_8_16_chars(); +static void biosfn_get_font_info(); +static void biosfn_alternate_prtsc(); +static void biosfn_switch_video_interface(); +static void biosfn_enable_video_refresh_control(); +static void biosfn_write_string(); +static void biosfn_read_state_info(); +static void biosfn_read_video_state_size(); +static Bit16u biosfn_save_video_state(); +static Bit16u biosfn_restore_video_state(); +extern Bit8u video_save_pointer_table[]; + +// This is for compiling with gcc2 and gcc3 +#define ASM_START #asm +#define ASM_END #endasm + +ASM_START + +MACRO SET_INT_VECTOR + push ds + xor ax, ax + mov ds, ax + mov ax, ?3 + mov ?1*4, ax + mov ax, ?2 + mov ?1*4+2, ax + pop ds +MEND + +ASM_END + +ASM_START +.text +.rom +.org 0 + +use16 386 + +vgabios_start: +.byte 0x55, 0xaa /* BIOS signature, required for BIOS extensions */ + +.byte 0x40 /* BIOS extension length in units of 512 bytes */ + + +vgabios_entry_point: + + jmp vgabios_init_func + +#ifdef PCIBIOS +.org 0x18 +.word vgabios_pci_data +#endif + +// Info from Bart Oldeman +.org 0x1e +.ascii "IBM" +.byte 0x00 + +vgabios_name: +.ascii "Plex86/Bochs VGABios" +#ifdef PCIBIOS +.ascii " (PCI)" +#endif +.ascii " " +.byte 0x00 + +vgabios_version: +#ifndef VGABIOS_VERS +.ascii "current-cvs" +#else +.ascii VGABIOS_VERS +#endif +.ascii " " + +vgabios_date: +.ascii VGABIOS_DATE +.byte 0x0a,0x0d +.byte 0x00 + +vgabios_copyright: +.ascii "(C) 2008 the LGPL VGABios developers Team" +.byte 0x0a,0x0d +.byte 0x00 + +vgabios_license: +.ascii "This VGA/VBE Bios is released under the GNU LGPL" +.byte 0x0a,0x0d +.byte 0x0a,0x0d +.byte 0x00 + +vgabios_website: +.ascii "Please visit :" +.byte 0x0a,0x0d +;;.ascii " . http://www.plex86.org" +;;.byte 0x0a,0x0d +.ascii " . http://bochs.sourceforge.net" +.byte 0x0a,0x0d +.ascii " . http://www.nongnu.org/vgabios" +.byte 0x0a,0x0d +.byte 0x0a,0x0d +.byte 0x00 + +#ifdef PCIBIOS +vgabios_pci_data: +.ascii "PCIR" +#ifdef CIRRUS +.word 0x1013 +.word 0x00b8 // CLGD5446 +#elif defined(VBE) +.word 0x1234 +.word 0x1111 // Bochs VBE support +#else +#error "Unknown PCI vendor and device id" +#endif +.word 0 // reserved +.word 0x18 // dlen +.byte 0 // revision +.byte 0x0 // class,hi: vga display +.word 0x300 // class,lo: vga display +.word 0x40 // bios size +.word 1 // revision +.byte 0 // intel x86 data +.byte 0x80 // last image +.word 0 // reserved +#endif + + +;; ============================================================================================ +;; +;; Init Entry point +;; +;; ============================================================================================ +vgabios_init_func: + +;; init vga card + call init_vga_card + +;; init basic bios vars + call init_bios_area + +#ifdef VBE +;; init vbe functions + call vbe_init +#endif + +;; set int10 vect + SET_INT_VECTOR(0x10, #0xC000, #vgabios_int10_handler) + +#ifdef CIRRUS + call cirrus_init +#endif + +;; display splash screen + call _display_splash_screen + +;; init video mode and clear the screen + mov ax,#0x0003 + int #0x10 + +;; show info + call _display_info + +#ifdef VBE +;; show vbe info + call vbe_display_info +#endif + +#ifdef CIRRUS +;; show cirrus info + call cirrus_display_info +#endif + + retf +ASM_END + +/* + * int10 handled here + */ +ASM_START +vgabios_int10_handler: + pushf +#ifdef DEBUG + push es + push ds + pusha + mov bx, #0xc000 + mov ds, bx + call _int10_debugmsg + popa + pop ds + pop es +#endif + cmp ah, #0x0f + jne int10_test_1A + call biosfn_get_video_mode + jmp int10_end +int10_test_1A: + cmp ah, #0x1a + jne int10_test_0B + call biosfn_group_1A + jmp int10_end +int10_test_0B: + cmp ah, #0x0b + jne int10_test_1103 + call biosfn_group_0B + jmp int10_end +int10_test_1103: + cmp ax, #0x1103 + jne int10_test_12 + call biosfn_set_text_block_specifier + jmp int10_end +int10_test_12: + cmp ah, #0x12 + jne int10_test_101B + cmp bl, #0x10 + jne int10_test_BL30 + call biosfn_get_ega_info + jmp int10_end +int10_test_BL30: + cmp bl, #0x30 + jne int10_test_BL31 + call biosfn_select_vert_res + jmp int10_end +int10_test_BL31: + cmp bl, #0x31 + jne int10_test_BL32 + call biosfn_enable_default_palette_loading + jmp int10_end +int10_test_BL32: + cmp bl, #0x32 + jne int10_test_BL33 + call biosfn_enable_video_addressing + jmp int10_end +int10_test_BL33: + cmp bl, #0x33 + jne int10_test_BL34 + call biosfn_enable_grayscale_summing + jmp int10_end +int10_test_BL34: + cmp bl, #0x34 + jne int10_normal + call biosfn_enable_cursor_emulation + jmp int10_end +int10_test_101B: + cmp ax, #0x101b + je int10_normal + cmp ah, #0x10 +#ifndef VBE + jne int10_normal +#else + jne int10_test_4F +#endif + call biosfn_group_10 + jmp int10_end +#ifdef VBE +int10_test_4F: + cmp ah, #0x4f + jne int10_normal + cmp al, #0x03 + jne int10_test_vbe_05 + call vbe_biosfn_return_current_mode + jmp int10_end +int10_test_vbe_05: + cmp al, #0x05 + jne int10_test_vbe_06 + call vbe_biosfn_display_window_control + jmp int10_end +int10_test_vbe_06: + cmp al, #0x06 + jne int10_test_vbe_07 + call vbe_biosfn_set_get_logical_scan_line_length + jmp int10_end +int10_test_vbe_07: + cmp al, #0x07 + jne int10_test_vbe_08 + call vbe_biosfn_set_get_display_start + jmp int10_end +int10_test_vbe_08: + cmp al, #0x08 + jne int10_test_vbe_0A + call vbe_biosfn_set_get_dac_palette_format + jmp int10_end +int10_test_vbe_0A: + cmp al, #0x0A + jne int10_normal + call vbe_biosfn_return_protected_mode_interface + jmp int10_end +#endif + +int10_normal: + push es + push ds + pusha + +;; We have to set ds to access the right data segment + mov bx, #0xc000 + mov ds, bx + call _int10_func + + popa + pop ds + pop es +int10_end: + popf + iret +ASM_END + +#include "vgatables.h" +#include "vgafonts.h" + +/* + * Boot time harware inits + */ +ASM_START +init_vga_card: +;; switch to color mode and enable CPU access 480 lines + mov dx, #0x3C2 + mov al, #0xC3 + outb dx,al + +;; more than 64k 3C4/04 + mov dx, #0x3C4 + mov al, #0x04 + outb dx,al + mov dx, #0x3C5 + mov al, #0x02 + outb dx,al + +#if defined(USE_BX_INFO) || defined(DEBUG) + mov bx, #msg_vga_init + push bx + call _printf + inc sp + inc sp +#endif + ret + +#if defined(USE_BX_INFO) || defined(DEBUG) +msg_vga_init: +.ascii "VGABios $Id: vgabios.c,v 1.72 2011/06/27 17:58:32 vruppert Exp $" +.byte 0x0d,0x0a,0x00 +#endif +ASM_END + +// -------------------------------------------------------------------------------------------- +/* + * Boot time bios area inits + */ +ASM_START +init_bios_area: + push ds + mov ax, # BIOSMEM_SEG + mov ds, ax + +;; init detected hardware BIOS Area + mov bx, # BIOSMEM_INITIAL_MODE + mov ax, [bx] + and ax, #0xffcf +;; set 80x25 color (not clear from RBIL but usual) + or ax, #0x0020 + mov [bx], ax + +;; Just for the first int10 find its children + +;; the default char height + mov bx, # BIOSMEM_CHAR_HEIGHT + mov al, #0x10 + mov [bx], al + +;; Clear the screen + mov bx, # BIOSMEM_VIDEO_CTL + mov al, #0x60 + mov [bx], al + +;; Set the basic screen we have + mov bx, # BIOSMEM_SWITCHES + mov al, #0xf9 + mov [bx], al + +;; Set the basic modeset options + mov bx, # BIOSMEM_MODESET_CTL + mov al, #0x51 + mov [bx], al + +;; Set the default MSR + mov bx, # BIOSMEM_CURRENT_MSR + mov al, #0x09 + mov [bx], al + + pop ds + ret + +_video_save_pointer_table: + .word _video_param_table + .word 0xc000 + + .word 0 /* XXX: fill it */ + .word 0 + + .word 0 /* XXX: fill it */ + .word 0 + + .word 0 /* XXX: fill it */ + .word 0 + + .word 0 /* XXX: fill it */ + .word 0 + + .word 0 /* XXX: fill it */ + .word 0 + + .word 0 /* XXX: fill it */ + .word 0 + +ASM_END + +// -------------------------------------------------------------------------------------------- +/* + * Boot time Splash screen + */ +static void display_splash_screen() +{ +} + +// -------------------------------------------------------------------------------------------- +/* + * Tell who we are + */ + +static void display_info() +{ +ASM_START + mov ax,#0xc000 + mov ds,ax + mov si,#vgabios_name + call _display_string + mov si,#vgabios_version + call _display_string + + ;;mov si,#vgabios_copyright + ;;call _display_string + ;;mov si,#crlf + ;;call _display_string + + mov si,#vgabios_license + call _display_string + mov si,#vgabios_website + call _display_string +ASM_END +} + +static void display_string() +{ + // Get length of string +ASM_START + mov ax,ds + mov es,ax + mov di,si + xor cx,cx + not cx + xor al,al + cld + repne + scasb + not cx + dec cx + push cx + + mov ax,#0x0300 + mov bx,#0x0000 + int #0x10 + + pop cx + mov ax,#0x1301 + mov bx,#0x000b + mov bp,si + int #0x10 +ASM_END +} + +// -------------------------------------------------------------------------------------------- +#ifdef DEBUG +static void int10_debugmsg(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS) + Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS; +{ + // 0E is write char... + if(GET_AH()!=0x0E) + printf("vgabios call ah%02x al%02x bx%04x cx%04x dx%04x\n",GET_AH(),GET_AL(),BX,CX,DX); +} +#endif + +// -------------------------------------------------------------------------------------------- +/* + * int10 main dispatcher + */ +static void int10_func(DI, SI, BP, SP, BX, DX, CX, AX, DS, ES, FLAGS) + Bit16u DI, SI, BP, SP, BX, DX, CX, AX, ES, DS, FLAGS; +{ + + // BIOS functions + switch(GET_AH()) + { + case 0x00: + biosfn_set_video_mode(GET_AL()); + switch(GET_AL()&0x7F) + {case 6: + SET_AL(0x3F); + break; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 7: + SET_AL(0x30); + break; + default: + SET_AL(0x20); + } + break; + case 0x01: + biosfn_set_cursor_shape(GET_CH(),GET_CL()); + break; + case 0x02: + biosfn_set_cursor_pos(GET_BH(),DX); + break; + case 0x03: + biosfn_get_cursor_pos(GET_BH(),&CX,&DX); + break; + case 0x04: + // Read light pen pos (unimplemented) +#ifdef DEBUG + unimplemented(); +#endif + AX=0x00; + BX=0x00; + CX=0x00; + DX=0x00; + break; + case 0x05: + biosfn_set_active_page(GET_AL()); + break; + case 0x06: + biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_UP); + break; + case 0x07: + biosfn_scroll(GET_AL(),GET_BH(),GET_CH(),GET_CL(),GET_DH(),GET_DL(),0xFF,SCROLL_DOWN); + break; + case 0x08: + biosfn_read_char_attr(GET_BH(),&AX); + break; + case 0x09: + biosfn_write_char_attr(GET_AL(),GET_BH(),GET_BL(),CX); + break; + case 0x0A: + biosfn_write_char_only(GET_AL(),GET_BH(),GET_BL(),CX); + break; + case 0x0C: + biosfn_write_pixel(GET_BH(),GET_AL(),CX,DX); + break; + case 0x0D: + biosfn_read_pixel(GET_BH(),CX,DX,&AX); + break; + case 0x0E: + // Ralf Brown Interrupt list is WRONG on bh(page) + // We do output only on the current page ! + biosfn_write_teletype(GET_AL(),0xff,GET_BL(),NO_ATTR); + break; + case 0x10: + // All other functions of group AH=0x10 rewritten in assembler + biosfn_perform_gray_scale_summing(BX,CX); + break; + case 0x11: + switch(GET_AL()) + { + case 0x00: + case 0x10: + biosfn_load_text_user_pat(GET_AL(),ES,BP,CX,DX,GET_BL(),GET_BH()); + break; + case 0x01: + case 0x11: + biosfn_load_text_8_14_pat(GET_AL(),GET_BL()); + break; + case 0x02: + case 0x12: + biosfn_load_text_8_8_pat(GET_AL(),GET_BL()); + break; + case 0x04: + case 0x14: + biosfn_load_text_8_16_pat(GET_AL(),GET_BL()); + break; + case 0x20: + biosfn_load_gfx_8_8_chars(ES,BP); + break; + case 0x21: + biosfn_load_gfx_user_chars(ES,BP,CX,GET_BL(),GET_DL()); + break; + case 0x22: + biosfn_load_gfx_8_14_chars(GET_BL()); + break; + case 0x23: + biosfn_load_gfx_8_8_dd_chars(GET_BL()); + break; + case 0x24: + biosfn_load_gfx_8_16_chars(GET_BL()); + break; + case 0x30: + biosfn_get_font_info(GET_BH(),&ES,&BP,&CX,&DX); + break; +#ifdef DEBUG + default: + unknown(); +#endif + } + + break; + case 0x12: + switch(GET_BL()) + { + case 0x20: + biosfn_alternate_prtsc(); + break; + case 0x35: + biosfn_switch_video_interface(GET_AL(),ES,DX); + SET_AL(0x12); + break; + case 0x36: + biosfn_enable_video_refresh_control(GET_AL()); + SET_AL(0x12); + break; +#ifdef DEBUG + default: + unknown(); +#endif + } + break; + case 0x13: + biosfn_write_string(GET_AL(),GET_BH(),GET_BL(),CX,GET_DH(),GET_DL(),ES,BP); + break; + case 0x1B: + biosfn_read_state_info(BX,ES,DI); + SET_AL(0x1B); + break; + case 0x1C: + switch(GET_AL()) + { + case 0x00: + biosfn_read_video_state_size(CX,&BX); + break; + case 0x01: + biosfn_save_video_state(CX,ES,BX); + break; + case 0x02: + biosfn_restore_video_state(CX,ES,BX); + break; +#ifdef DEBUG + default: + unknown(); +#endif + } + SET_AL(0x1C); + break; + +#ifdef VBE + case 0x4f: + if (vbe_has_vbe_display()) { + switch(GET_AL()) + { + case 0x00: + vbe_biosfn_return_controller_information(&AX,ES,DI); + break; + case 0x01: + vbe_biosfn_return_mode_information(&AX,CX,ES,DI); + break; + case 0x02: + vbe_biosfn_set_mode(&AX,BX,ES,DI); + break; + case 0x04: + vbe_biosfn_save_restore_state(&AX, CX, DX, ES, &BX); + break; + case 0x09: + //FIXME +#ifdef DEBUG + unimplemented(); +#endif + // function failed + AX=0x100; + break; + case 0x0A: + //FIXME +#ifdef DEBUG + unimplemented(); +#endif + // function failed + AX=0x100; + break; + default: +#ifdef DEBUG + unknown(); +#endif + // function failed + AX=0x100; + } + } + else { + // No VBE display + AX=0x0100; + } + break; +#endif + +#ifdef DEBUG + default: + unknown(); +#endif + } +} + +static void load_dac_palette(num) Bit8u num; +{ + Bit8u *palette; + Bit16u i; + + // Set the whole dac always, from 0 + outb(VGAREG_DAC_WRITE_ADDRESS,0x00); + + // From which palette + switch (num) + { + case 0: + palette=&palette0; + break; + case 1: + palette=&palette1; + break; + case 2: + palette=&palette2; + break; + case 3: + palette=&palette3; + break; + } + // Always 256*3 values + for (i=0;i<0x0100;i++) + { + if(i<=dac_regs[num]) + { + outb(VGAREG_DAC_DATA,palette[(i*3)+0]); + outb(VGAREG_DAC_DATA,palette[(i*3)+1]); + outb(VGAREG_DAC_DATA,palette[(i*3)+2]); + } + else + { + outb(VGAREG_DAC_DATA,0); + outb(VGAREG_DAC_DATA,0); + outb(VGAREG_DAC_DATA,0); + } + } +} + +// ============================================================================================ +// +// BIOS functions +// +// ============================================================================================ + +static void biosfn_set_video_mode(mode) Bit8u mode; +{// mode: Bit 7 is 1 if no clear screen + + // Should we clear the screen ? + Bit8u noclearmem=mode&0x80; + Bit8u line,mmask,*palette,vpti; + Bit16u i,twidth,theightm1,cheight; + Bit8u modeset_ctl,video_ctl,vga_switches; + Bit16u crtc_addr; + +#ifdef VBE + if (vbe_has_vbe_display()) { + dispi_set_enable(VBE_DISPI_DISABLED); + } +#endif // def VBE + + // The real mode + mode=mode&0x7f; + + // find the entry in the video modes + line=find_vga_entry(mode); + +#ifdef DEBUG + printf("mode search %02x found line %02x\n",mode,line); +#endif + + if(line==0xFF) + return; + + vpti=line_to_vpti[line]; + twidth=video_param_table[vpti].twidth; + theightm1=video_param_table[vpti].theightm1; + cheight=video_param_table[vpti].cheight; + + // Read the bios vga control + video_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL); + + // Read the bios vga switches + vga_switches=read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES); + + // Read the bios mode set control + modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); + + // Then we know the number of lines + // FIXME + + // if palette loading (bit 3 of modeset ctl = 0) + if((modeset_ctl&0x08)==0) + { + // Set the PEL mask + outb(VGAREG_PEL_MASK,vga_modes[line].pelmask); + + load_dac_palette(vga_modes[line].dacmodel); + + if((modeset_ctl&0x02)==0x02) + { + biosfn_perform_gray_scale_summing(0x00, 0x100); + } + } + + // Reset Attribute Ctl flip-flop + inb(VGAREG_ACTL_RESET); + + // Set Attribute Ctl + for(i=0;i<=0x13;i++) + {outb(VGAREG_ACTL_ADDRESS,i); + outb(VGAREG_ACTL_WRITE_DATA,video_param_table[vpti].actl_regs[i]); + } + outb(VGAREG_ACTL_ADDRESS,0x14); + outb(VGAREG_ACTL_WRITE_DATA,0x00); + + // Set Sequencer Ctl + outb(VGAREG_SEQU_ADDRESS,0); + outb(VGAREG_SEQU_DATA,0x03); + for(i=1;i<=4;i++) + {outb(VGAREG_SEQU_ADDRESS,i); + outb(VGAREG_SEQU_DATA,video_param_table[vpti].sequ_regs[i - 1]); + } + + // Set Grafx Ctl + for(i=0;i<=8;i++) + {outb(VGAREG_GRDC_ADDRESS,i); + outb(VGAREG_GRDC_DATA,video_param_table[vpti].grdc_regs[i]); + } + + // Set CRTC address VGA or MDA + crtc_addr=vga_modes[line].memmodel==MTEXT?VGAREG_MDA_CRTC_ADDRESS:VGAREG_VGA_CRTC_ADDRESS; + + // Disable CRTC write protection + outw(crtc_addr,0x0011); + // Set CRTC regs + for(i=0;i<=0x18;i++) + {outb(crtc_addr,i); + outb(crtc_addr+1,video_param_table[vpti].crtc_regs[i]); + } + + // Set the misc register + outb(VGAREG_WRITE_MISC_OUTPUT,video_param_table[vpti].miscreg); + + // Enable video + outb(VGAREG_ACTL_ADDRESS,0x20); + inb(VGAREG_ACTL_RESET); + + if(noclearmem==0x00) + { + if(vga_modes[line].class==TEXT) + { + memsetw(vga_modes[line].sstart,0,0x0720,0x4000); // 32k + } + else + { + if(mode<0x0d) + { + memsetw(vga_modes[line].sstart,0,0x0000,0x4000); // 32k + } + else + { + outb( VGAREG_SEQU_ADDRESS, 0x02 ); + mmask = inb( VGAREG_SEQU_DATA ); + outb( VGAREG_SEQU_DATA, 0x0f ); // all planes + memsetw(vga_modes[line].sstart,0,0x0000,0x8000); // 64k + outb( VGAREG_SEQU_DATA, mmask ); + } + } + } + + // Set the BIOS mem + write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode); + write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS,twidth); + write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,*(Bit16u *)&video_param_table[vpti].slength_l); + write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_addr); + write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS,theightm1); + write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,cheight); + write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|noclearmem)); + write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES,0xF9); + write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); + + // FIXME We nearly have the good tables. to be reworked + write_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now + write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER, video_save_pointer_table); + write_word(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2, 0xc000); + + // FIXME + write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x00); // Unavailable on vanilla vga, but... + write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x00); // Unavailable on vanilla vga, but... + + // Set cursor shape + if(vga_modes[line].class==TEXT) + { + biosfn_set_cursor_shape(0x06,0x07); + } + + // Set cursor pos for page 0..7 + for(i=0;i<8;i++) + biosfn_set_cursor_pos(i,0x0000); + + // Set active page 0 + biosfn_set_active_page(0x00); + + // Write the fonts in memory + if(vga_modes[line].class==TEXT) + { +ASM_START + ;; copy and activate 8x16 font + mov ax, #0x1104 + mov bl, #0x00 + int #0x10 + mov ax, #0x1103 + mov bl, #0x00 + int #0x10 +ASM_END + } + + // Set the ints 0x1F and 0x43 +ASM_START + SET_INT_VECTOR(0x1f, #0xC000, #_vgafont8+128*8) +ASM_END + + switch(cheight) + {case 8: +ASM_START + SET_INT_VECTOR(0x43, #0xC000, #_vgafont8) +ASM_END + break; + case 14: +ASM_START + SET_INT_VECTOR(0x43, #0xC000, #_vgafont14) +ASM_END + break; + case 16: +ASM_START + SET_INT_VECTOR(0x43, #0xC000, #_vgafont16) +ASM_END + break; + } +} + +// -------------------------------------------------------------------------------------------- +static void biosfn_set_cursor_shape (CH,CL) +Bit8u CH;Bit8u CL; +{Bit16u cheight,curs,crtc_addr; + Bit8u modeset_ctl; + + CH&=0x3f; + CL&=0x1f; + + curs=(CH<<8)+CL; + write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE,curs); + + modeset_ctl=read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); + cheight = read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); + if((modeset_ctl&0x01) && (cheight>8) && (CL<8) && (CH<0x20)) + { + if(CL!=(CH+1)) + { + CH = ((CH+1) * cheight / 8) -1; + } + else + { + CH = ((CL+1) * cheight / 8) - 2; + } + CL = ((CL+1) * cheight / 8) - 1; + } + + // CTRC regs 0x0a and 0x0b + crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + outb(crtc_addr,0x0a); + outb(crtc_addr+1,CH); + outb(crtc_addr,0x0b); + outb(crtc_addr+1,CL); +} + +// -------------------------------------------------------------------------------------------- +static void biosfn_set_cursor_pos (page, cursor) +Bit8u page;Bit16u cursor; +{ + Bit8u xcurs,ycurs,current; + Bit16u nbcols,nbrows,address,crtc_addr; + + // Should not happen... + if(page>7)return; + + // Bios cursor pos + write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*page, cursor); + + // Set the hardware cursor + current=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); + if(page==current) + { + // Get the dimensions + nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); + nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; + + xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; + + // Calculate the address knowing nbcols nbrows and page num + address=SCREEN_IO_START(nbcols,nbrows,page)+xcurs+ycurs*nbcols; + + // CRTC regs 0x0e and 0x0f + crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + outb(crtc_addr,0x0e); + outb(crtc_addr+1,(address&0xff00)>>8); + outb(crtc_addr,0x0f); + outb(crtc_addr+1,address&0x00ff); + } +} + +// -------------------------------------------------------------------------------------------- +static void biosfn_get_cursor_pos (page,shape, pos) +Bit8u page;Bit16u *shape;Bit16u *pos; +{ + Bit16u ss=get_SS(); + + // Default + write_word(ss, shape, 0); + write_word(ss, pos, 0); + + if(page>7)return; + // FIXME should handle VGA 14/16 lines + write_word(ss,shape,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE)); + write_word(ss,pos,read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2)); +} + +// -------------------------------------------------------------------------------------------- +static void biosfn_set_active_page (page) +Bit8u page; +{ + Bit16u cursor,dummy,crtc_addr; + Bit16u nbcols,nbrows,address; + Bit8u mode,line; + + if(page>7)return; + + // Get the mode + mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); + line=find_vga_entry(mode); + if(line==0xFF)return; + + // Get pos curs pos for the right page + biosfn_get_cursor_pos(page,&dummy,&cursor); + + if(vga_modes[line].class==TEXT) + { + // Get the dimensions + nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); + nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; + + // Calculate the address knowing nbcols nbrows and page num + address=SCREEN_MEM_START(nbcols,nbrows,page); + write_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START,address); + + // Start address + address=SCREEN_IO_START(nbcols,nbrows,page); + } + else + { + address = page * (*(Bit16u *)&video_param_table[line_to_vpti[line]].slength_l); + } + + // CRTC regs 0x0c and 0x0d + crtc_addr=read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + outb(crtc_addr,0x0c); + outb(crtc_addr+1,(address&0xff00)>>8); + outb(crtc_addr,0x0d); + outb(crtc_addr+1,address&0x00ff); + + // And change the BIOS page + write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE,page); + +#ifdef DEBUG + printf("Set active page %02x address %04x\n",page,address); +#endif + + // Display the cursor, now the page is active + biosfn_set_cursor_pos(page,cursor); +} + +// -------------------------------------------------------------------------------------------- +static void vgamem_copy_pl4(xstart,ysrc,ydest,cols,nbcols,cheight) +Bit8u xstart;Bit8u ysrc;Bit8u ydest;Bit8u cols;Bit8u nbcols;Bit8u cheight; +{ + Bit16u src,dest; + Bit8u i; + + src=ysrc*cheight*nbcols+xstart; + dest=ydest*cheight*nbcols+xstart; + outw(VGAREG_GRDC_ADDRESS, 0x0105); + for(i=0;i<cheight;i++) + { + memcpyb(0xa000,dest+i*nbcols,0xa000,src+i*nbcols,cols); + } + outw(VGAREG_GRDC_ADDRESS, 0x0005); +} + +// -------------------------------------------------------------------------------------------- +static void vgamem_fill_pl4(xstart,ystart,cols,nbcols,cheight,attr) +Bit8u xstart;Bit8u ystart;Bit8u cols;Bit8u nbcols;Bit8u cheight;Bit8u attr; +{ + Bit16u dest; + Bit8u i; + + dest=ystart*cheight*nbcols+xstart; + outw(VGAREG_GRDC_ADDRESS, 0x0205); + for(i=0;i<cheight;i++) + { + memsetb(0xa000,dest+i*nbcols,attr,cols); + } + outw(VGAREG_GRDC_ADDRESS, 0x0005); +} + +// -------------------------------------------------------------------------------------------- +static void vgamem_copy_cga(xstart,ysrc,ydest,cols,nbcols,cheight) +Bit8u xstart;Bit8u ysrc;Bit8u ydest;Bit8u cols;Bit8u nbcols;Bit8u cheight; +{ + Bit16u src,dest; + Bit8u i; + + src=((ysrc*cheight*nbcols)>>1)+xstart; + dest=((ydest*cheight*nbcols)>>1)+xstart; + for(i=0;i<cheight;i++) + { + if (i & 1) + memcpyb(0xb800,0x2000+dest+(i>>1)*nbcols,0xb800,0x2000+src+(i>>1)*nbcols,cols); + else + memcpyb(0xb800,dest+(i>>1)*nbcols,0xb800,src+(i>>1)*nbcols,cols); + } +} + +// -------------------------------------------------------------------------------------------- +static void vgamem_fill_cga(xstart,ystart,cols,nbcols,cheight,attr) +Bit8u xstart;Bit8u ystart;Bit8u cols;Bit8u nbcols;Bit8u cheight;Bit8u attr; +{ + Bit16u dest; + Bit8u i; + + dest=((ystart*cheight*nbcols)>>1)+xstart; + for(i=0;i<cheight;i++) + { + if (i & 1) + memsetb(0xb800,0x2000+dest+(i>>1)*nbcols,attr,cols); + else + memsetb(0xb800,dest+(i>>1)*nbcols,attr,cols); + } +} + +// -------------------------------------------------------------------------------------------- +static void biosfn_scroll (nblines,attr,rul,cul,rlr,clr,page,dir) +Bit8u nblines;Bit8u attr;Bit8u rul;Bit8u cul;Bit8u rlr;Bit8u clr;Bit8u page;Bit8u dir; +{ + // page == 0xFF if current + + Bit8u mode,line,cheight,bpp,cols; + Bit16u nbcols,nbrows,i; + Bit16u address; + + if(rul>rlr)return; + if(cul>clr)return; + + // Get the mode + mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); + line=find_vga_entry(mode); + if(line==0xFF)return; + + // Get the dimensions + nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; + nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); + + // Get the current page + if(page==0xFF) + page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); + + if(rlr>=nbrows)rlr=nbrows-1; + if(clr>=nbcols)clr=nbcols-1; + if(nblines>nbrows)nblines=0; + cols=clr-cul+1; + + if(vga_modes[line].class==TEXT) + { + // Compute the address + address=SCREEN_MEM_START(nbcols,nbrows,page); +#ifdef DEBUG + printf("Scroll, address %04x (%04x %04x %02x)\n",address,nbrows,nbcols,page); +#endif + + if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1) + { + memsetw(vga_modes[line].sstart,address,(Bit16u)attr*0x100+' ',nbrows*nbcols); + } + else + {// if Scroll up + if(dir==SCROLL_UP) + {for(i=rul;i<=rlr;i++) + { + if((i+nblines>rlr)||(nblines==0)) + memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols); + else + memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i+nblines)*nbcols+cul)*2,cols); + } + } + else + {for(i=rlr;i>=rul;i--) + { + if((i<rul+nblines)||(nblines==0)) + memsetw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,(Bit16u)attr*0x100+' ',cols); + else + memcpyw(vga_modes[line].sstart,address+(i*nbcols+cul)*2,vga_modes[line].sstart,((i-nblines)*nbcols+cul)*2,cols); + if (i>rlr) break; + } + } + } + } + else + { + // FIXME gfx mode not complete + cheight=video_param_table[line_to_vpti[line]].cheight; + switch(vga_modes[line].memmodel) + { + case PLANAR4: + case PLANAR1: + if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1) + { + outw(VGAREG_GRDC_ADDRESS, 0x0205); + memsetb(vga_modes[line].sstart,0,attr,nbrows*nbcols*cheight); + outw(VGAREG_GRDC_ADDRESS, 0x0005); + } + else + {// if Scroll up + if(dir==SCROLL_UP) + {for(i=rul;i<=rlr;i++) + { + if((i+nblines>rlr)||(nblines==0)) + vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr); + else + vgamem_copy_pl4(cul,i+nblines,i,cols,nbcols,cheight); + } + } + else + {for(i=rlr;i>=rul;i--) + { + if((i<rul+nblines)||(nblines==0)) + vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr); + else + vgamem_copy_pl4(cul,i,i-nblines,cols,nbcols,cheight); + if (i>rlr) break; + } + } + } + break; + case CGA: + bpp=vga_modes[line].pixbits; + if(nblines==0&&rul==0&&cul==0&&rlr==nbrows-1&&clr==nbcols-1) + { + memsetb(vga_modes[line].sstart,0,attr,nbrows*nbcols*cheight*bpp); + } + else + { + if(bpp==2) + { + cul<<=1; + cols<<=1; + nbcols<<=1; + } + // if Scroll up + if(dir==SCROLL_UP) + {for(i=rul;i<=rlr;i++) + { + if((i+nblines>rlr)||(nblines==0)) + vgamem_fill_cga(cul,i,cols,nbcols,cheight,attr); + else + vgamem_copy_cga(cul,i+nblines,i,cols,nbcols,cheight); + } + } + else + {for(i=rlr;i>=rul;i--) + { + if((i<rul+nblines)||(nblines==0)) + vgamem_fill_cga(cul,i,cols,nbcols,cheight,attr); + else + vgamem_copy_cga(cul,i,i-nblines,cols,nbcols,cheight); + if (i>rlr) break; + } + } + } + break; +#ifdef DEBUG + default: + printf("Scroll in graphics mode "); + unimplemented(); +#endif + } + } +} + +// -------------------------------------------------------------------------------------------- +static void biosfn_read_char_attr (page,car) +Bit8u page;Bit16u *car; +{Bit16u ss=get_SS(); + Bit8u xcurs,ycurs,mode,line; + Bit16u nbcols,nbrows,address; + Bit16u cursor,dummy; + + // Get the mode + mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); + line=find_vga_entry(mode); + if(line==0xFF)return; + + // Get the cursor pos for the page + biosfn_get_cursor_pos(page,&dummy,&cursor); + xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; + + // Get the dimensions + nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; + nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); + + if(vga_modes[line].class==TEXT) + { + // Compute the address + address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2; + + write_word(ss,car,read_word(vga_modes[line].sstart,address)); + } + else + { + // FIXME gfx mode +#ifdef DEBUG + unimplemented(); +#endif + } +} + +// -------------------------------------------------------------------------------------------- +static void write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight) +Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;Bit8u cheight; +{ + Bit8u i,j,mask; + Bit8u *fdata; + Bit16u addr,dest,src; + + switch(cheight) + {case 14: + fdata = &vgafont14; + break; + case 16: + fdata = &vgafont16; + break; + default: + fdata = &vgafont8; + } + addr=xcurs+ycurs*cheight*nbcols; + src = car * cheight; + outw(VGAREG_SEQU_ADDRESS, 0x0f02); + outw(VGAREG_GRDC_ADDRESS, 0x0205); + if(attr&0x80) + { + outw(VGAREG_GRDC_ADDRESS, 0x1803); + } + else + { + outw(VGAREG_GRDC_ADDRESS, 0x0003); + } + for(i=0;i<cheight;i++) + { + dest=addr+i*nbcols; + for(j=0;j<8;j++) + { + mask=0x80>>j; + outw(VGAREG_GRDC_ADDRESS, (mask << 8) | 0x08); + read_byte(0xa000,dest); + if(fdata[src+i]&mask) + { + write_byte(0xa000,dest,attr&0x0f); + } + else + { + write_byte(0xa000,dest,0x00); + } + } + } +ASM_START + mov dx, # VGAREG_GRDC_ADDRESS + mov ax, #0xff08 + out dx, ax + mov ax, #0x0005 + out dx, ax + mov ax, #0x0003 + out dx, ax +ASM_END +} + +// -------------------------------------------------------------------------------------------- +static void write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp) +Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols;Bit8u bpp; +{ + Bit8u i,j,mask,data; + Bit8u *fdata; + Bit16u addr,dest,src; + + fdata = &vgafont8; + addr=(xcurs*bpp)+ycurs*320; + src = car * 8; + for(i=0;i<8;i++) + { + dest=addr+(i>>1)*80; + if (i & 1) dest += 0x2000; + mask = 0x80; + if (bpp == 1) + { + if (attr & 0x80) + { + data = read_byte(0xb800,dest); + } + else + { + data = 0x00; + } + for(j=0;j<8;j++) + { + if (fdata[src+i] & mask) + { + if (attr & 0x80) + { + data ^= (attr & 0x01) << (7-j); + } + else + { + data |= (attr & 0x01) << (7-j); + } + } + mask >>= 1; + } + write_byte(0xb800,dest,data); + } + else + { + while (mask > 0) + { + if (attr & 0x80) + { + data = read_byte(0xb800,dest); + } + else + { + data = 0x00; + } + for(j=0;j<4;j++) + { + if (fdata[src+i] & mask) + { + if (attr & 0x80) + { + data ^= (attr & 0x03) << ((3-j)*2); + } + else + { + data |= (attr & 0x03) << ((3-j)*2); + } + } + mask >>= 1; + } + write_byte(0xb800,dest,data); + dest += 1; + } + } + } +} + +// -------------------------------------------------------------------------------------------- +static void write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols) +Bit8u car;Bit8u attr;Bit8u xcurs;Bit8u ycurs;Bit8u nbcols; +{ + Bit8u i,j,mask,data; + Bit8u *fdata; + Bit16u addr,dest,src; + + fdata = &vgafont8; + addr=xcurs*8+ycurs*nbcols*64; + src = car * 8; + for(i=0;i<8;i++) + { + dest=addr+i*nbcols*8; + mask = 0x80; + for(j=0;j<8;j++) + { + data = 0x00; + if (fdata[src+i] & mask) + { + data = attr; + } + write_byte(0xa000,dest+j,data); + mask >>= 1; + } + } +} + +// -------------------------------------------------------------------------------------------- +static void biosfn_write_char_attr (car,page,attr,count) +Bit8u car;Bit8u page;Bit8u attr;Bit16u count; +{ + Bit8u cheight,xcurs,ycurs,mode,line,bpp; + Bit16u nbcols,nbrows,address; + Bit16u cursor,dummy; + + // Get the mode + mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); + line=find_vga_entry(mode); + if(line==0xFF)return; + + // Get the cursor pos for the page + biosfn_get_cursor_pos(page,&dummy,&cursor); + xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; + + // Get the dimensions + nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; + nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); + + if(vga_modes[line].class==TEXT) + { + // Compute the address + address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2; + + dummy=((Bit16u)attr<<8)+car; + memsetw(vga_modes[line].sstart,address,dummy,count); + } + else + { + // FIXME gfx mode not complete + cheight=video_param_table[line_to_vpti[line]].cheight; + bpp=vga_modes[line].pixbits; + while((count-->0) && (xcurs<nbcols)) + { + switch(vga_modes[line].memmodel) + { + case PLANAR4: + case PLANAR1: + write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight); + break; + case CGA: + write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp); + break; + case LINEAR8: + write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols); + break; +#ifdef DEBUG + default: + unimplemented(); +#endif + } + xcurs++; + } + } +} + +// -------------------------------------------------------------------------------------------- +static void biosfn_write_char_only (car,page,attr,count) +Bit8u car;Bit8u page;Bit8u attr;Bit16u count; +{ + Bit8u cheight,xcurs,ycurs,mode,line,bpp; + Bit16u nbcols,nbrows,address; + Bit16u cursor,dummy; + + // Get the mode + mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); + line=find_vga_entry(mode); + if(line==0xFF)return; + + // Get the cursor pos for the page + biosfn_get_cursor_pos(page,&dummy,&cursor); + xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; + + // Get the dimensions + nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; + nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); + + if(vga_modes[line].class==TEXT) + { + // Compute the address + address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2; + + while(count-->0) + {write_byte(vga_modes[line].sstart,address,car); + address+=2; + } + } + else + { + // FIXME gfx mode not complete + cheight=video_param_table[line_to_vpti[line]].cheight; + bpp=vga_modes[line].pixbits; + while((count-->0) && (xcurs<nbcols)) + { + switch(vga_modes[line].memmodel) + { + case PLANAR4: + case PLANAR1: + write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight); + break; + case CGA: + write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp); + break; + case LINEAR8: + write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols); + break; +#ifdef DEBUG + default: + unimplemented(); +#endif + } + xcurs++; + } + } +} + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_group_0B: + cmp bh, #0x00 + je biosfn_set_border_color + cmp bh, #0x01 + je biosfn_set_palette +#ifdef DEBUG + call _unknown +#endif + ret +biosfn_set_border_color: + push ax + push bx + push cx + push dx + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov dx, # VGAREG_ACTL_ADDRESS + mov al, #0x00 + out dx, al + mov al, bl + and al, #0x0f + test al, #0x08 + jz set_low_border + add al, #0x08 +set_low_border: + out dx, al + mov cl, #0x01 + and bl, #0x10 +set_intensity_loop: + mov dx, # VGAREG_ACTL_ADDRESS + mov al, cl + out dx, al + mov dx, # VGAREG_ACTL_READ_DATA + in al, dx + and al, #0xef + or al, bl + mov dx, # VGAREG_ACTL_ADDRESS + out dx, al + inc cl + cmp cl, #0x04 + jne set_intensity_loop + mov al, #0x20 + out dx, al + pop dx + pop cx + pop bx + pop ax + ret +biosfn_set_palette: + push ax + push bx + push cx + push dx + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov cl, #0x01 + and bl, #0x01 +set_cga_palette_loop: + mov dx, # VGAREG_ACTL_ADDRESS + mov al, cl + out dx, al + mov dx, # VGAREG_ACTL_READ_DATA + in al, dx + and al, #0xfe + or al, bl + mov dx, # VGAREG_ACTL_ADDRESS + out dx, al + inc cl + cmp cl, #0x04 + jne set_cga_palette_loop + mov al, #0x20 + out dx, al + pop dx + pop cx + pop bx + pop ax + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +static void biosfn_write_pixel (BH,AL,CX,DX) Bit8u BH;Bit8u AL;Bit16u CX;Bit16u DX; +{ + Bit8u mode,line,mask,attr,data; + Bit16u addr; + + // Get the mode + mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); + line=find_vga_entry(mode); + if(line==0xFF)return; + if(vga_modes[line].class==TEXT)return; + + switch(vga_modes[line].memmodel) + { + case PLANAR4: + case PLANAR1: + addr = CX/8+DX*read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); + mask = 0x80 >> (CX & 0x07); + outw(VGAREG_GRDC_ADDRESS, (mask << 8) | 0x08); + outw(VGAREG_GRDC_ADDRESS, 0x0205); + data = read_byte(0xa000,addr); + if (AL & 0x80) + { + outw(VGAREG_GRDC_ADDRESS, 0x1803); + } + write_byte(0xa000,addr,AL); +ASM_START + mov dx, # VGAREG_GRDC_ADDRESS + mov ax, #0xff08 + out dx, ax + mov ax, #0x0005 + out dx, ax + mov ax, #0x0003 + out dx, ax +ASM_END + break; + case CGA: + if(vga_modes[line].pixbits==2) + { + addr=(CX>>2)+(DX>>1)*80; + } + else + { + addr=(CX>>3)+(DX>>1)*80; + } + if (DX & 1) addr += 0x2000; + data = read_byte(0xb800,addr); + if(vga_modes[line].pixbits==2) + { + attr = (AL & 0x03) << ((3 - (CX & 0x03)) * 2); + mask = 0x03 << ((3 - (CX & 0x03)) * 2); + } + else + { + attr = (AL & 0x01) << (7 - (CX & 0x07)); + mask = 0x01 << (7 - (CX & 0x07)); + } + if (AL & 0x80) + { + data ^= attr; + } + else + { + data &= ~mask; + data |= attr; + } + write_byte(0xb800,addr,data); + break; + case LINEAR8: + addr=CX+DX*(read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); + write_byte(0xa000,addr,AL); + break; +#ifdef DEBUG + default: + unimplemented(); +#endif + } +} + +// -------------------------------------------------------------------------------------------- +static void biosfn_read_pixel (BH,CX,DX,AX) Bit8u BH;Bit16u CX;Bit16u DX;Bit16u *AX; +{ + Bit8u mode,line,mask,attr,data,i; + Bit16u addr; + Bit16u ss=get_SS(); + + // Get the mode + mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); + line=find_vga_entry(mode); + if(line==0xFF)return; + if(vga_modes[line].class==TEXT)return; + + switch(vga_modes[line].memmodel) + { + case PLANAR4: + case PLANAR1: + addr = CX/8+DX*read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); + mask = 0x80 >> (CX & 0x07); + attr = 0x00; + for(i=0;i<4;i++) + { + outw(VGAREG_GRDC_ADDRESS, (i << 8) | 0x04); + data = read_byte(0xa000,addr) & mask; + if (data > 0) attr |= (0x01 << i); + } + break; + case CGA: + addr=(CX>>2)+(DX>>1)*80; + if (DX & 1) addr += 0x2000; + data = read_byte(0xb800,addr); + if(vga_modes[line].pixbits==2) + { + attr = (data >> ((3 - (CX & 0x03)) * 2)) & 0x03; + } + else + { + attr = (data >> (7 - (CX & 0x07))) & 0x01; + } + break; + case LINEAR8: + addr=CX+DX*(read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8); + attr=read_byte(0xa000,addr); + break; + default: +#ifdef DEBUG + unimplemented(); +#endif + attr = 0; + } + write_word(ss,AX,(read_word(ss,AX) & 0xff00) | attr); +} + +// -------------------------------------------------------------------------------------------- +static void biosfn_write_teletype (car, page, attr, flag) +Bit8u car;Bit8u page;Bit8u attr;Bit8u flag; +{// flag = WITH_ATTR / NO_ATTR + + Bit8u cheight,xcurs,ycurs,mode,line,bpp; + Bit16u nbcols,nbrows,address; + Bit16u cursor,dummy; + + // special case if page is 0xff, use current page + if(page==0xff) + page=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); + + // Get the mode + mode=read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE); + line=find_vga_entry(mode); + if(line==0xFF)return; + + // Get the cursor pos for the page + biosfn_get_cursor_pos(page,&dummy,&cursor); + xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; + + // Get the dimensions + nbrows=read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1; + nbcols=read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); + + switch(car) + { + case 7: + //FIXME should beep + break; + + case 8: + if(xcurs>0)xcurs--; + break; + + case '\r': + xcurs=0; + break; + + case '\n': + ycurs++; + break; + + case '\t': + do + { + biosfn_write_teletype(' ',page,attr,flag); + biosfn_get_cursor_pos(page,&dummy,&cursor); + xcurs=cursor&0x00ff;ycurs=(cursor&0xff00)>>8; + }while(xcurs%8==0); + break; + + default: + + if(vga_modes[line].class==TEXT) + { + // Compute the address + address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+ycurs*nbcols)*2; + + // Write the char + write_byte(vga_modes[line].sstart,address,car); + + if(flag==WITH_ATTR) + write_byte(vga_modes[line].sstart,address+1,attr); + } + else + { + // FIXME gfx mode not complete + cheight=video_param_table[line_to_vpti[line]].cheight; + bpp=vga_modes[line].pixbits; + switch(vga_modes[line].memmodel) + { + case PLANAR4: + case PLANAR1: + write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight); + break; + case CGA: + write_gfx_char_cga(car,attr,xcurs,ycurs,nbcols,bpp); + break; + case LINEAR8: + write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols); + break; +#ifdef DEBUG + default: + unimplemented(); +#endif + } + } + xcurs++; + } + + // Do we need to wrap ? + if(xcurs==nbcols) + {xcurs=0; + ycurs++; + } + + // Do we need to scroll ? + if(ycurs==nbrows) + { + if(vga_modes[line].class==TEXT) + { + address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+(ycurs-1)*nbcols)*2; + attr=read_byte(vga_modes[line].sstart,address+1); + biosfn_scroll(0x01,attr,0,0,nbrows-1,nbcols-1,page,SCROLL_UP); + } + else + { + biosfn_scroll(0x01,0x00,0,0,nbrows-1,nbcols-1,page,SCROLL_UP); + } + ycurs-=1; + } + + // Set the cursor for the page + cursor=ycurs; cursor<<=8; cursor+=xcurs; + biosfn_set_cursor_pos(page,cursor); +} + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_get_video_mode: + push ds + mov ax, # BIOSMEM_SEG + mov ds, ax + push bx + mov bx, # BIOSMEM_CURRENT_PAGE + mov al, [bx] + pop bx + mov bh, al + push bx + mov bx, # BIOSMEM_VIDEO_CTL + mov ah, [bx] + and ah, #0x80 + mov bx, # BIOSMEM_CURRENT_MODE + mov al, [bx] + or al, ah + mov bx, # BIOSMEM_NB_COLS + mov ah, [bx] + pop bx + pop ds + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_group_10: + cmp al, #0x00 + jne int10_test_1001 + jmp biosfn_set_single_palette_reg +int10_test_1001: + cmp al, #0x01 + jne int10_test_1002 + jmp biosfn_set_overscan_border_color +int10_test_1002: + cmp al, #0x02 + jne int10_test_1003 + jmp biosfn_set_all_palette_reg +int10_test_1003: + cmp al, #0x03 + jne int10_test_1007 + jmp biosfn_toggle_intensity +int10_test_1007: + cmp al, #0x07 + jne int10_test_1008 + jmp biosfn_get_single_palette_reg +int10_test_1008: + cmp al, #0x08 + jne int10_test_1009 + jmp biosfn_read_overscan_border_color +int10_test_1009: + cmp al, #0x09 + jne int10_test_1010 + jmp biosfn_get_all_palette_reg +int10_test_1010: + cmp al, #0x10 + jne int10_test_1012 + jmp biosfn_set_single_dac_reg +int10_test_1012: + cmp al, #0x12 + jne int10_test_1013 + jmp biosfn_set_all_dac_reg +int10_test_1013: + cmp al, #0x13 + jne int10_test_1015 + jmp biosfn_select_video_dac_color_page +int10_test_1015: + cmp al, #0x15 + jne int10_test_1017 + jmp biosfn_read_single_dac_reg +int10_test_1017: + cmp al, #0x17 + jne int10_test_1018 + jmp biosfn_read_all_dac_reg +int10_test_1018: + cmp al, #0x18 + jne int10_test_1019 + jmp biosfn_set_pel_mask +int10_test_1019: + cmp al, #0x19 + jne int10_test_101A + jmp biosfn_read_pel_mask +int10_test_101A: + cmp al, #0x1a + jne int10_group_10_unknown + jmp biosfn_read_video_dac_state +int10_group_10_unknown: +#ifdef DEBUG + call _unknown +#endif + ret + +biosfn_set_single_palette_reg: + cmp bl, #0x14 + ja no_actl_reg1 + push ax + push dx + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov dx, # VGAREG_ACTL_ADDRESS + mov al, bl + out dx, al + mov al, bh + out dx, al + mov al, #0x20 + out dx, al + pop dx + pop ax +no_actl_reg1: + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_set_overscan_border_color: + push bx + mov bl, #0x11 + call biosfn_set_single_palette_reg + pop bx + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_set_all_palette_reg: + push ax + push bx + push cx + push dx + mov bx, dx + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov cl, #0x00 + mov dx, # VGAREG_ACTL_ADDRESS +set_palette_loop: + mov al, cl + out dx, al + seg es + mov al, [bx] + out dx, al + inc bx + inc cl + cmp cl, #0x10 + jne set_palette_loop + mov al, #0x11 + out dx, al + seg es + mov al, [bx] + out dx, al + mov al, #0x20 + out dx, al + pop dx + pop cx + pop bx + pop ax + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_toggle_intensity: + push ax + push bx + push dx + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov dx, # VGAREG_ACTL_ADDRESS + mov al, #0x10 + out dx, al + mov dx, # VGAREG_ACTL_READ_DATA + in al, dx + and al, #0xf7 + and bl, #0x01 + shl bl, 3 + or al, bl + mov dx, # VGAREG_ACTL_ADDRESS + out dx, al + mov al, #0x20 + out dx, al + pop dx + pop bx + pop ax + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_get_single_palette_reg: + cmp bl, #0x14 + ja no_actl_reg2 + push ax + push dx + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov dx, # VGAREG_ACTL_ADDRESS + mov al, bl + out dx, al + mov dx, # VGAREG_ACTL_READ_DATA + in al, dx + mov bh, al + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov dx, # VGAREG_ACTL_ADDRESS + mov al, #0x20 + out dx, al + pop dx + pop ax +no_actl_reg2: + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_read_overscan_border_color: + push ax + push bx + mov bl, #0x11 + call biosfn_get_single_palette_reg + mov al, bh + pop bx + mov bh, al + pop ax + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_get_all_palette_reg: + push ax + push bx + push cx + push dx + mov bx, dx + mov cl, #0x00 +get_palette_loop: + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov dx, # VGAREG_ACTL_ADDRESS + mov al, cl + out dx, al + mov dx, # VGAREG_ACTL_READ_DATA + in al, dx + seg es + mov [bx], al + inc bx + inc cl + cmp cl, #0x10 + jne get_palette_loop + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov dx, # VGAREG_ACTL_ADDRESS + mov al, #0x11 + out dx, al + mov dx, # VGAREG_ACTL_READ_DATA + in al, dx + seg es + mov [bx], al + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov dx, # VGAREG_ACTL_ADDRESS + mov al, #0x20 + out dx, al + pop dx + pop cx + pop bx + pop ax + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_set_single_dac_reg: + push ax + push dx + mov dx, # VGAREG_DAC_WRITE_ADDRESS + mov al, bl + out dx, al + mov dx, # VGAREG_DAC_DATA + pop ax + push ax + mov al, ah + out dx, al + mov al, ch + out dx, al + mov al, cl + out dx, al + pop dx + pop ax + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_set_all_dac_reg: + push ax + push bx + push cx + push dx + mov dx, # VGAREG_DAC_WRITE_ADDRESS + mov al, bl + out dx, al + pop dx + push dx + mov bx, dx + mov dx, # VGAREG_DAC_DATA +set_dac_loop: + seg es + mov al, [bx] + out dx, al + inc bx + seg es + mov al, [bx] + out dx, al + inc bx + seg es + mov al, [bx] + out dx, al + inc bx + dec cx + jnz set_dac_loop + pop dx + pop cx + pop bx + pop ax + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_select_video_dac_color_page: + push ax + push bx + push dx + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov dx, # VGAREG_ACTL_ADDRESS + mov al, #0x10 + out dx, al + mov dx, # VGAREG_ACTL_READ_DATA + in al, dx + and bl, #0x01 + jnz set_dac_page + and al, #0x7f + shl bh, 7 + or al, bh + mov dx, # VGAREG_ACTL_ADDRESS + out dx, al + jmp set_actl_normal +set_dac_page: + push ax + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov dx, # VGAREG_ACTL_ADDRESS + mov al, #0x14 + out dx, al + pop ax + and al, #0x80 + jnz set_dac_16_page + shl bh, 2 +set_dac_16_page: + and bh, #0x0f + mov al, bh + out dx, al +set_actl_normal: + mov al, #0x20 + out dx, al + pop dx + pop bx + pop ax + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_read_single_dac_reg: + push ax + push dx + mov dx, # VGAREG_DAC_READ_ADDRESS + mov al, bl + out dx, al + pop ax + mov ah, al + mov dx, # VGAREG_DAC_DATA + in al, dx + xchg al, ah + push ax + in al, dx + mov ch, al + in al, dx + mov cl, al + pop dx + pop ax + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_read_all_dac_reg: + push ax + push bx + push cx + push dx + mov dx, # VGAREG_DAC_READ_ADDRESS + mov al, bl + out dx, al + pop dx + push dx + mov bx, dx + mov dx, # VGAREG_DAC_DATA +read_dac_loop: + in al, dx + seg es + mov [bx], al + inc bx + in al, dx + seg es + mov [bx], al + inc bx + in al, dx + seg es + mov [bx], al + inc bx + dec cx + jnz read_dac_loop + pop dx + pop cx + pop bx + pop ax + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_set_pel_mask: + push ax + push dx + mov dx, # VGAREG_PEL_MASK + mov al, bl + out dx, al + pop dx + pop ax + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_read_pel_mask: + push ax + push dx + mov dx, # VGAREG_PEL_MASK + in al, dx + mov bl, al + pop dx + pop ax + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_read_video_dac_state: + push ax + push dx + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov dx, # VGAREG_ACTL_ADDRESS + mov al, #0x10 + out dx, al + mov dx, # VGAREG_ACTL_READ_DATA + in al, dx + mov bl, al + shr bl, 7 + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov dx, # VGAREG_ACTL_ADDRESS + mov al, #0x14 + out dx, al + mov dx, # VGAREG_ACTL_READ_DATA + in al, dx + mov bh, al + and bh, #0x0f + test bl, #0x01 + jnz get_dac_16_page + shr bh, 2 +get_dac_16_page: + mov dx, # VGAREG_ACTL_RESET + in al, dx + mov dx, # VGAREG_ACTL_ADDRESS + mov al, #0x20 + out dx, al + pop dx + pop ax + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +static void biosfn_perform_gray_scale_summing (start,count) +Bit16u start;Bit16u count; +{Bit8u r,g,b; + Bit16u i; + Bit16u index; + + inb(VGAREG_ACTL_RESET); + outb(VGAREG_ACTL_ADDRESS,0x00); + + for( index = 0; index < count; index++ ) + { + // set read address and switch to read mode + outb(VGAREG_DAC_READ_ADDRESS,start); + // get 6-bit wide RGB data values + r=inb( VGAREG_DAC_DATA ); + g=inb( VGAREG_DAC_DATA ); + b=inb( VGAREG_DAC_DATA ); + + // intensity = ( 0.3 * Red ) + ( 0.59 * Green ) + ( 0.11 * Blue ) + i = ( ( 77*r + 151*g + 28*b ) + 0x80 ) >> 8; + + if(i>0x3f)i=0x3f; + + // set write address and switch to write mode + outb(VGAREG_DAC_WRITE_ADDRESS,start); + // write new intensity value + outb( VGAREG_DAC_DATA, i&0xff ); + outb( VGAREG_DAC_DATA, i&0xff ); + outb( VGAREG_DAC_DATA, i&0xff ); + start++; + } + inb(VGAREG_ACTL_RESET); + outb(VGAREG_ACTL_ADDRESS,0x20); +} + +// -------------------------------------------------------------------------------------------- +static void get_font_access() +{ +ASM_START + mov dx, # VGAREG_SEQU_ADDRESS + mov ax, #0x0100 + out dx, ax + mov ax, #0x0402 + out dx, ax + mov ax, #0x0704 + out dx, ax + mov ax, #0x0300 + out dx, ax + mov dx, # VGAREG_GRDC_ADDRESS + mov ax, #0x0204 + out dx, ax + mov ax, #0x0005 + out dx, ax + mov ax, #0x0406 + out dx, ax +ASM_END +} + +static void release_font_access() +{ +ASM_START + mov dx, # VGAREG_SEQU_ADDRESS + mov ax, #0x0100 + out dx, ax + mov ax, #0x0302 + out dx, ax + mov ax, #0x0304 + out dx, ax + mov ax, #0x0300 + out dx, ax + mov dx, # VGAREG_READ_MISC_OUTPUT + in al, dx + and al, #0x01 + shl al, 2 + or al, #0x0a + mov ah, al + mov al, #0x06 + mov dx, # VGAREG_GRDC_ADDRESS + out dx, ax + mov ax, #0x0004 + out dx, ax + mov ax, #0x1005 + out dx, ax +ASM_END +} + +ASM_START +idiv_u: + xor dx,dx + div bx + ret +ASM_END + +static void set_scan_lines(lines) Bit8u lines; +{ + Bit16u crtc_addr,cols,page,vde; + Bit8u crtc_r9,ovl,rows; + + crtc_addr = read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS); + outb(crtc_addr, 0x09); + crtc_r9 = inb(crtc_addr+1); + crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1); + outb(crtc_addr+1, crtc_r9); + if(lines==8) + { + biosfn_set_cursor_shape(0x06,0x07); + } + else + { + biosfn_set_cursor_shape(lines-4,lines-3); + } + write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, lines); + outb(crtc_addr, 0x12); + vde = inb(crtc_addr+1); + outb(crtc_addr, 0x07); + ovl = inb(crtc_addr+1); + vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1); + rows = vde / lines; + write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, rows-1); + cols = read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS); + write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, rows * cols * 2); +} + +static void biosfn_load_text_user_pat (AL,ES,BP,CX,DX,BL,BH) Bit8u AL;Bit16u ES;Bit16u BP;Bit16u CX;Bit16u DX;Bit8u BL;Bit8u BH; +{ + Bit16u blockaddr,dest,i,src; + + get_font_access(); + blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); + for(i=0;i<CX;i++) + { + src = BP + i * BH; + dest = blockaddr + (DX + i) * 32; + memcpyb(0xA000, dest, ES, src, BH); + } + release_font_access(); + if(AL>=0x10) + { + set_scan_lines(BH); + } +} + +static void biosfn_load_text_8_14_pat (AL,BL) Bit8u AL;Bit8u BL; +{ + Bit16u blockaddr,dest,i,src; + + get_font_access(); + blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); + for(i=0;i<0x100;i++) + { + src = i * 14; + dest = blockaddr + i * 32; + memcpyb(0xA000, dest, 0xC000, vgafont14+src, 14); + } + release_font_access(); + if(AL>=0x10) + { + set_scan_lines(14); + } +} + +static void biosfn_load_text_8_8_pat (AL,BL) Bit8u AL;Bit8u BL; +{ + Bit16u blockaddr,dest,i,src; + + get_font_access(); + blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); + for(i=0;i<0x100;i++) + { + src = i * 8; + dest = blockaddr + i * 32; + memcpyb(0xA000, dest, 0xC000, vgafont8+src, 8); + } + release_font_access(); + if(AL>=0x10) + { + set_scan_lines(8); + } +} + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_set_text_block_specifier: + push ax + push dx + mov dx, # VGAREG_SEQU_ADDRESS + mov ah, bl + mov al, #0x03 + out dx, ax + pop dx + pop ax + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +static void biosfn_load_text_8_16_pat (AL,BL) Bit8u AL;Bit8u BL; +{ + Bit16u blockaddr,dest,i,src; + + get_font_access(); + blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11); + for(i=0;i<0x100;i++) + { + src = i * 16; + dest = blockaddr + i * 32; + memcpyb(0xA000, dest, 0xC000, vgafont16+src, 16); + } + release_font_access(); + if(AL>=0x10) + { + set_scan_lines(16); + } +} + +static void biosfn_load_gfx_8_8_chars (ES,BP) Bit16u ES;Bit16u BP; +{ +#ifdef DEBUG + unimplemented(); +#endif +} +static void biosfn_load_gfx_user_chars (ES,BP,CX,BL,DL) Bit16u ES;Bit16u BP;Bit16u CX;Bit8u BL;Bit8u DL; +{ +#ifdef DEBUG + unimplemented(); +#endif +} +static void biosfn_load_gfx_8_14_chars (BL) Bit8u BL; +{ +#ifdef DEBUG + unimplemented(); +#endif +} +static void biosfn_load_gfx_8_8_dd_chars (BL) Bit8u BL; +{ +#ifdef DEBUG + unimplemented(); +#endif +} +static void biosfn_load_gfx_8_16_chars (BL) Bit8u BL; +{ +#ifdef DEBUG + unimplemented(); +#endif +} +// -------------------------------------------------------------------------------------------- +static void biosfn_get_font_info (BH,ES,BP,CX,DX) +Bit8u BH;Bit16u *ES;Bit16u *BP;Bit16u *CX;Bit16u *DX; +{Bit16u ss=get_SS(); + + switch(BH) + {case 0x00: + write_word(ss,ES,read_word(0x00,0x1f*4)); + write_word(ss,BP,read_word(0x00,(0x1f*4)+2)); + break; + case 0x01: + write_word(ss,ES,read_word(0x00,0x43*4)); + write_word(ss,BP,read_word(0x00,(0x43*4)+2)); + break; + case 0x02: + write_word(ss,ES,0xC000); + write_word(ss,BP,vgafont14); + break; + case 0x03: + write_word(ss,ES,0xC000); + write_word(ss,BP,vgafont8); + break; + case 0x04: + write_word(ss,ES,0xC000); + write_word(ss,BP,vgafont8+128*8); + break; + case 0x05: + write_word(ss,ES,0xC000); + write_word(ss,BP,vgafont14alt); + break; + case 0x06: + write_word(ss,ES,0xC000); + write_word(ss,BP,vgafont16); + break; + case 0x07: + write_word(ss,ES,0xC000); + write_word(ss,BP,vgafont16alt); + break; + default: + #ifdef DEBUG + printf("Get font info BH(%02x) was discarded\n",BH); + #endif + return; + } + // Set byte/char of on screen font + write_word(ss,CX,(Bit16u)read_byte(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT)); + + // Set Highest char row + write_word(ss,DX,(Bit16u)read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)); +} + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_get_ega_info: + push ds + push ax + mov ax, # BIOSMEM_SEG + mov ds, ax + xor ch, ch + mov bx, # BIOSMEM_SWITCHES + mov cl, [bx] + and cl, #0x0f + mov bx, # BIOSMEM_CRTC_ADDRESS + mov ax, [bx] + mov bx, #0x0003 + cmp ax, # VGAREG_MDA_CRTC_ADDRESS + jne mode_ega_color + mov bh, #0x01 +mode_ega_color: + pop ax + pop ds + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +static void biosfn_alternate_prtsc() +{ +#ifdef DEBUG + unimplemented(); +#endif +} + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_select_vert_res: + +; res : 00 200 lines, 01 350 lines, 02 400 lines + + push ds + push bx + push dx + mov dl, al + mov ax, # BIOSMEM_SEG + mov ds, ax + mov bx, # BIOSMEM_MODESET_CTL + mov al, [bx] + mov bx, # BIOSMEM_SWITCHES + mov ah, [bx] + cmp dl, #0x01 + je vert_res_350 + jb vert_res_200 + cmp dl, #0x02 + je vert_res_400 +#ifdef DEBUG + mov al, dl + xor ah, ah + push ax + mov bx, #msg_vert_res + push bx + call _printf + add sp, #4 +#endif + jmp set_retcode +vert_res_400: + + ; reset modeset ctl bit 7 and set bit 4 + ; set switches bit 3-0 to 0x09 + + and al, #0x7f + or al, #0x10 + and ah, #0xf0 + or ah, #0x09 + jnz set_vert_res +vert_res_350: + + ; reset modeset ctl bit 7 and bit 4 + ; set switches bit 3-0 to 0x09 + + and al, #0x6f + and ah, #0xf0 + or ah, #0x09 + jnz set_vert_res +vert_res_200: + + ; set modeset ctl bit 7 and reset bit 4 + ; set switches bit 3-0 to 0x08 + + and al, #0xef + or al, #0x80 + and ah, #0xf0 + or ah, #0x08 +set_vert_res: + mov bx, # BIOSMEM_MODESET_CTL + mov [bx], al + mov bx, # BIOSMEM_SWITCHES + mov [bx], ah +set_retcode: + mov ax, #0x1212 + pop dx + pop bx + pop ds + ret + +#ifdef DEBUG +msg_vert_res: +.ascii "Select vert res (%02x) was discarded" +.byte 0x0d,0x0a,0x00 +#endif + + +biosfn_enable_default_palette_loading: + push ds + push bx + push dx + mov dl, al + and dl, #0x01 + shl dl, 3 + mov ax, # BIOSMEM_SEG + mov ds, ax + mov bx, # BIOSMEM_MODESET_CTL + mov al, [bx] + and al, #0xf7 + or al, dl + mov [bx], al + mov ax, #0x1212 + pop dx + pop bx + pop ds + ret + + +biosfn_enable_video_addressing: + push bx + push dx + mov bl, al + and bl, #0x01 + xor bl, #0x01 + shl bl, 1 + mov dx, # VGAREG_READ_MISC_OUTPUT + in al, dx + and al, #0xfd + or al, bl + mov dx, # VGAREG_WRITE_MISC_OUTPUT + out dx, al + mov ax, #0x1212 + pop dx + pop bx + ret + + +biosfn_enable_grayscale_summing: + push ds + push bx + push dx + mov dl, al + and dl, #0x01 + xor dl, #0x01 + shl dl, 1 + mov ax, # BIOSMEM_SEG + mov ds, ax + mov bx, # BIOSMEM_MODESET_CTL + mov al, [bx] + and al, #0xfd + or al, dl + mov [bx], al + mov ax, #0x1212 + pop dx + pop bx + pop ds + ret + + +biosfn_enable_cursor_emulation: + push ds + push bx + push dx + mov dl, al + and dl, #0x01 + xor dl, #0x01 + mov ax, # BIOSMEM_SEG + mov ds, ax + mov bx, # BIOSMEM_MODESET_CTL + mov al, [bx] + and al, #0xfe + or al, dl + mov [bx], al + mov ax, #0x1212 + pop dx + pop bx + pop ds + ret +ASM_END + +// -------------------------------------------------------------------------------------------- +static void biosfn_switch_video_interface (AL,ES,DX) Bit8u AL;Bit16u ES;Bit16u DX; +{ +#ifdef DEBUG + unimplemented(); +#endif +} +static void biosfn_enable_video_refresh_control (AL) Bit8u AL; +{ +#ifdef DEBUG + unimplemented(); +#endif +} + +// -------------------------------------------------------------------------------------------- +static void biosfn_write_string (flag,page,attr,count,row,col,seg,offset) +Bit8u flag;Bit8u page;Bit8u attr;Bit16u count;Bit8u row;Bit8u col;Bit16u seg;Bit16u offset; +{ + Bit16u newcurs,oldcurs,dummy; + Bit8u car,carattr; + + // Read curs info for the page + biosfn_get_cursor_pos(page,&dummy,&oldcurs); + + // if row=0xff special case : use current cursor position + if(row==0xff) + {col=oldcurs&0x00ff; + row=(oldcurs&0xff00)>>8; + } + + newcurs=row; newcurs<<=8; newcurs+=col; + biosfn_set_cursor_pos(page,newcurs); + + while(count--!=0) + { + car=read_byte(seg,offset++); + if((flag&0x02)!=0) + attr=read_byte(seg,offset++); + + biosfn_write_teletype(car,page,attr,WITH_ATTR); + } + + // Set back curs pos + if((flag&0x01)==0) + biosfn_set_cursor_pos(page,oldcurs); +} + +// -------------------------------------------------------------------------------------------- +ASM_START +biosfn_group_1A: + cmp al, #0x00 + je biosfn_read_display_code + cmp al, #0x01 + je biosfn_set_display_code +#ifdef DEBUG + call _unknown +#endif + ret +biosfn_read_display_code: + push ds + push ax + mov ax, # BIOSMEM_SEG + mov ds, ax + mov bx, # BIOSMEM_DCC_INDEX + mov al, [bx] + mov bl, al + xor bh, bh + pop ax + mov al, ah + pop ds + ret +biosfn_set_display_code: + push ds + push ax + push bx + mov ax, # BIOSMEM_SEG + mov ds, ax + mov ax, bx + mov bx, # BIOSMEM_DCC_INDEX + mov [bx], al +#ifdef DEBUG + mov al, ah + xor ah, ah + push ax + mov bx, #msg_alt_dcc + push bx + call _printf + add sp, #4 +#endif + pop bx + pop ax + mov al, ah + pop ds + ret + +#ifdef DEBUG +msg_alt_dcc: +.ascii "Alternate Display code (%02x) was discarded" +.byte 0x0d,0x0a,0x00 +#endif +ASM_END + +// -------------------------------------------------------------------------------------------- +static void biosfn_read_state_info (BX,ES,DI) +Bit16u BX;Bit16u ES;Bit16u DI; +{ + // Address of static functionality table + write_word(ES,DI+0x00,&static_functionality); + write_word(ES,DI+0x02,0xC000); + + // Hard coded copy from BIOS area. Should it be cleaner ? + memcpyb(ES,DI+0x04,BIOSMEM_SEG,0x49,30); + memcpyb(ES,DI+0x22,BIOSMEM_SEG,0x84,3); + + write_byte(ES,DI+0x25,read_byte(BIOSMEM_SEG,BIOSMEM_DCC_INDEX)); + write_byte(ES,DI+0x26,0); + write_byte(ES,DI+0x27,16); + write_byte(ES,DI+0x28,0); + write_byte(ES,DI+0x29,8); + write_byte(ES,DI+0x2a,2); + write_byte(ES,DI+0x2b,0); + write_byte(ES,DI+0x2c,0); + write_byte(ES,DI+0x31,3); + write_byte(ES,DI+0x32,0); + + memsetb(ES,DI+0x33,0,13); +} + +// -------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------- +static Bit16u biosfn_read_video_state_size2 (CX) + Bit16u CX; +{ + Bit16u size; + size = 0; + if (CX & 1) { + size += 0x46; + } + if (CX & 2) { + size += (5 + 8 + 5) * 2 + 6; + } + if (CX & 4) { + size += 3 + 256 * 3 + 1; +} + return size; +} + +static void biosfn_read_video_state_size (CX, BX) + Bit16u CX; Bit16u *BX; +{ + Bit16u ss=get_SS(); + write_word(ss, BX, biosfn_read_video_state_size2(CX)); +} + +static Bit16u biosfn_save_video_state (CX,ES,BX) + Bit16u CX;Bit16u ES;Bit16u BX; +{ + Bit16u i, v, crtc_addr, ar_index; + + crtc_addr = read_word(BIOSMEM_SEG, BIOSMEM_CRTC_ADDRESS); + if (CX & 1) { + write_byte(ES, BX, inb(VGAREG_SEQU_ADDRESS)); BX++; + write_byte(ES, BX, inb(crtc_addr)); BX++; + write_byte(ES, BX, inb(VGAREG_GRDC_ADDRESS)); BX++; + inb(VGAREG_ACTL_RESET); + ar_index = inb(VGAREG_ACTL_ADDRESS); + write_byte(ES, BX, ar_index); BX++; + write_byte(ES, BX, inb(VGAREG_READ_FEATURE_CTL)); BX++; + + for(i=1;i<=4;i++){ + outb(VGAREG_SEQU_ADDRESS, i); + write_byte(ES, BX, inb(VGAREG_SEQU_DATA)); BX++; + } + outb(VGAREG_SEQU_ADDRESS, 0); + write_byte(ES, BX, inb(VGAREG_SEQU_DATA)); BX++; + + for(i=0;i<=0x18;i++) { + outb(crtc_addr,i); + write_byte(ES, BX, inb(crtc_addr+1)); BX++; + } + + for(i=0;i<=0x13;i++) { + inb(VGAREG_ACTL_RESET); + outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20)); + write_byte(ES, BX, inb(VGAREG_ACTL_READ_DATA)); BX++; + } + inb(VGAREG_ACTL_RESET); + + for(i=0;i<=8;i++) { + outb(VGAREG_GRDC_ADDRESS,i); + write_byte(ES, BX, inb(VGAREG_GRDC_DATA)); BX++; + } + + write_word(ES, BX, crtc_addr); BX+= 2; + + /* XXX: read plane latches */ + write_byte(ES, BX, 0); BX++; + write_byte(ES, BX, 0); BX++; + write_byte(ES, BX, 0); BX++; + write_byte(ES, BX, 0); BX++; + } + if (CX & 2) { + write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)); BX++; + write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)); BX += 2; + write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)); BX += 2; + write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)); BX += 2; + write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)); BX++; + write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT)); BX += 2; + write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL)); BX++; + write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES)); BX++; + write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)); BX++; + write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE)); BX += 2; + for(i=0;i<8;i++) { + write_word(ES, BX, read_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*i)); + BX += 2; + } + write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START)); BX += 2; + write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE)); BX++; + /* current font */ + write_word(ES, BX, read_word(0, 0x1f * 4)); BX += 2; + write_word(ES, BX, read_word(0, 0x1f * 4 + 2)); BX += 2; + write_word(ES, BX, read_word(0, 0x43 * 4)); BX += 2; + write_word(ES, BX, read_word(0, 0x43 * 4 + 2)); BX += 2; + } + if (CX & 4) { + /* XXX: check this */ + write_byte(ES, BX, inb(VGAREG_DAC_STATE)); BX++; /* read/write mode dac */ + write_byte(ES, BX, inb(VGAREG_DAC_WRITE_ADDRESS)); BX++; /* pix address */ + write_byte(ES, BX, inb(VGAREG_PEL_MASK)); BX++; + // Set the whole dac always, from 0 + outb(VGAREG_DAC_WRITE_ADDRESS,0x00); + for(i=0;i<256*3;i++) { + write_byte(ES, BX, inb(VGAREG_DAC_DATA)); BX++; + } + write_byte(ES, BX, 0); BX++; /* color select register */ + } + return BX; +} + +static Bit16u biosfn_restore_video_state (CX,ES,BX) + Bit16u CX;Bit16u ES;Bit16u BX; +{ + Bit16u i, crtc_addr, v, addr1, ar_index; + + if (CX & 1) { + // Reset Attribute Ctl flip-flop + inb(VGAREG_ACTL_RESET); + + crtc_addr = read_word(ES, BX + 0x40); + addr1 = BX; + BX += 5; + + for(i=1;i<=4;i++){ + outb(VGAREG_SEQU_ADDRESS, i); + outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++; + } + outb(VGAREG_SEQU_ADDRESS, 0); + outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++; + + // Disable CRTC write protection + outw(crtc_addr,0x0011); + // Set CRTC regs + for(i=0;i<=0x18;i++) { + if (i != 0x11) { + outb(crtc_addr,i); + outb(crtc_addr+1, read_byte(ES, BX)); + } + BX++; + } + // select crtc base address + v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01; + if (crtc_addr = 0x3d4) + v |= 0x01; + outb(VGAREG_WRITE_MISC_OUTPUT, v); + + // enable write protection if needed + outb(crtc_addr, 0x11); + outb(crtc_addr+1, read_byte(ES, BX - 0x18 + 0x11)); + + // Set Attribute Ctl + ar_index = read_byte(ES, addr1 + 0x03); + inb(VGAREG_ACTL_RESET); + for(i=0;i<=0x13;i++) { + outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20)); + outb(VGAREG_ACTL_WRITE_DATA, read_byte(ES, BX)); BX++; + } + outb(VGAREG_ACTL_ADDRESS, ar_index); + inb(VGAREG_ACTL_RESET); + + for(i=0;i<=8;i++) { + outb(VGAREG_GRDC_ADDRESS,i); + outb(VGAREG_GRDC_DATA, read_byte(ES, BX)); BX++; + } + BX += 2; /* crtc_addr */ + BX += 4; /* plane latches */ + + outb(VGAREG_SEQU_ADDRESS, read_byte(ES, addr1)); addr1++; + outb(crtc_addr, read_byte(ES, addr1)); addr1++; + outb(VGAREG_GRDC_ADDRESS, read_byte(ES, addr1)); addr1++; + addr1++; + outb(crtc_addr - 0x4 + 0xa, read_byte(ES, addr1)); addr1++; + } + if (CX & 2) { + write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE, read_byte(ES, BX)); BX++; + write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS, read_word(ES, BX)); BX += 2; + write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, read_word(ES, BX)); BX += 2; + write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS, read_word(ES, BX)); BX += 2; + write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, read_byte(ES, BX)); BX++; + write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, read_word(ES, BX)); BX += 2; + write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL, read_byte(ES, BX)); BX++; + write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES, read_byte(ES, BX)); BX++; + write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL, read_byte(ES, BX)); BX++; + write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE, read_word(ES, BX)); BX += 2; + for(i=0;i<8;i++) { + write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*i, read_word(ES, BX)); + BX += 2; + } + write_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START, read_word(ES, BX)); BX += 2; + write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE, read_byte(ES, BX)); BX++; + /* current font */ + write_word(0, 0x1f * 4, read_word(ES, BX)); BX += 2; + write_word(0, 0x1f * 4 + 2, read_word(ES, BX)); BX += 2; + write_word(0, 0x43 * 4, read_word(ES, BX)); BX += 2; + write_word(0, 0x43 * 4 + 2, read_word(ES, BX)); BX += 2; + } + if (CX & 4) { + BX++; + v = read_byte(ES, BX); BX++; + outb(VGAREG_PEL_MASK, read_byte(ES, BX)); BX++; + // Set the whole dac always, from 0 + outb(VGAREG_DAC_WRITE_ADDRESS,0x00); + for(i=0;i<256*3;i++) { + outb(VGAREG_DAC_DATA, read_byte(ES, BX)); BX++; + } + BX++; + outb(VGAREG_DAC_WRITE_ADDRESS, v); + } + return BX; +} + +// ============================================================================================ +// +// Video Utils +// +// ============================================================================================ + +// -------------------------------------------------------------------------------------------- +static Bit8u find_vga_entry(mode) +Bit8u mode; +{ + Bit8u i,line=0xFF; + for(i=0;i<=MODE_MAX;i++) + if(vga_modes[i].svgamode==mode) + {line=i; + break; + } + return line; +} + +/* =========================================================== */ +/* + * Misc Utils +*/ +/* =========================================================== */ + +// -------------------------------------------------------------------------------------------- +static void memsetb(seg,offset,value,count) + Bit16u seg; + Bit16u offset; + Bit16u value; + Bit16u count; +{ +ASM_START + push bp + mov bp, sp + + push ax + push cx + push es + push di + + mov cx, 10[bp] ; count + cmp cx, #0x00 + je memsetb_end + mov ax, 4[bp] ; segment + mov es, ax + mov ax, 6[bp] ; offset + mov di, ax + mov al, 8[bp] ; value + cld + rep + stosb + +memsetb_end: + pop di + pop es + pop cx + pop ax + + pop bp +ASM_END +} + +// -------------------------------------------------------------------------------------------- +static void memsetw(seg,offset,value,count) + Bit16u seg; + Bit16u offset; + Bit16u value; + Bit16u count; +{ +ASM_START + push bp + mov bp, sp + + push ax + push cx + push es + push di + + mov cx, 10[bp] ; count + cmp cx, #0x00 + je memsetw_end + mov ax, 4[bp] ; segment + mov es, ax + mov ax, 6[bp] ; offset + mov di, ax + mov ax, 8[bp] ; value + cld + rep + stosw + +memsetw_end: + pop di + pop es + pop cx + pop ax + + pop bp +ASM_END +} + +// -------------------------------------------------------------------------------------------- +static void memcpyb(dseg,doffset,sseg,soffset,count) + Bit16u dseg; + Bit16u doffset; + Bit16u sseg; + Bit16u soffset; + Bit16u count; +{ +ASM_START + push bp + mov bp, sp + + push ax + push cx + push es + push di + push ds + push si + + mov cx, 12[bp] ; count + cmp cx, #0x0000 + je memcpyb_end + mov ax, 4[bp] ; dsegment + mov es, ax + mov ax, 6[bp] ; doffset + mov di, ax + mov ax, 8[bp] ; ssegment + mov ds, ax + mov ax, 10[bp] ; soffset + mov si, ax + cld + rep + movsb + +memcpyb_end: + pop si + pop ds + pop di + pop es + pop cx + pop ax + + pop bp +ASM_END +} + +// -------------------------------------------------------------------------------------------- +static void memcpyw(dseg,doffset,sseg,soffset,count) + Bit16u dseg; + Bit16u doffset; + Bit16u sseg; + Bit16u soffset; + Bit16u count; +{ +ASM_START + push bp + mov bp, sp + + push ax + push cx + push es + push di + push ds + push si + + mov cx, 12[bp] ; count + cmp cx, #0x0000 + je memcpyw_end + mov ax, 4[bp] ; dsegment + mov es, ax + mov ax, 6[bp] ; doffset + mov di, ax + mov ax, 8[bp] ; ssegment + mov ds, ax + mov ax, 10[bp] ; soffset + mov si, ax + cld + rep + movsw + +memcpyw_end: + pop si + pop ds + pop di + pop es + pop cx + pop ax + + pop bp +ASM_END +} + +/* =========================================================== */ +/* + * These functions where ripped from Kevin's rombios.c +*/ +/* =========================================================== */ + +// -------------------------------------------------------------------------------------------- +static Bit8u +read_byte(seg, offset) + Bit16u seg; + Bit16u offset; +{ +ASM_START + push bp + mov bp, sp + + push bx + push ds + mov ax, 4[bp] ; segment + mov ds, ax + mov bx, 6[bp] ; offset + mov al, [bx] + ;; al = return value (byte) + pop ds + pop bx + + pop bp +ASM_END +} + +// -------------------------------------------------------------------------------------------- +static Bit16u +read_word(seg, offset) + Bit16u seg; + Bit16u offset; +{ +ASM_START + push bp + mov bp, sp + + push bx + push ds + mov ax, 4[bp] ; segment + mov ds, ax + mov bx, 6[bp] ; offset + mov ax, [bx] + ;; ax = return value (word) + pop ds + pop bx + + pop bp +ASM_END +} + +// -------------------------------------------------------------------------------------------- +static void +write_byte(seg, offset, data) + Bit16u seg; + Bit16u offset; + Bit8u data; +{ +ASM_START + push bp + mov bp, sp + + push ax + push bx + push ds + mov ax, 4[bp] ; segment + mov ds, ax + mov bx, 6[bp] ; offset + mov al, 8[bp] ; data byte + mov [bx], al ; write data byte + pop ds + pop bx + pop ax + + pop bp +ASM_END +} + +// -------------------------------------------------------------------------------------------- +static void +write_word(seg, offset, data) + Bit16u seg; + Bit16u offset; + Bit16u data; +{ +ASM_START + push bp + mov bp, sp + + push ax + push bx + push ds + mov ax, 4[bp] ; segment + mov ds, ax + mov bx, 6[bp] ; offset + mov ax, 8[bp] ; data word + mov [bx], ax ; write data word + pop ds + pop bx + pop ax + + pop bp +ASM_END +} + +// -------------------------------------------------------------------------------------------- + Bit8u +inb(port) + Bit16u port; +{ +ASM_START + push bp + mov bp, sp + + push dx + mov dx, 4[bp] + in al, dx + pop dx + + pop bp +ASM_END +} + + Bit16u +inw(port) + Bit16u port; +{ +ASM_START + push bp + mov bp, sp + + push dx + mov dx, 4[bp] + in ax, dx + pop dx + + pop bp +ASM_END +} + +// -------------------------------------------------------------------------------------------- + void +outb(port, val) + Bit16u port; + Bit8u val; +{ +ASM_START + push bp + mov bp, sp + + push ax + push dx + mov dx, 4[bp] + mov al, 6[bp] + out dx, al + pop dx + pop ax + + pop bp +ASM_END +} + +// -------------------------------------------------------------------------------------------- + void +outw(port, val) + Bit16u port; + Bit16u val; +{ +ASM_START + push bp + mov bp, sp + + push ax + push dx + mov dx, 4[bp] + mov ax, 6[bp] + out dx, ax + pop dx + pop ax + + pop bp +ASM_END +} + +Bit16u get_SS() +{ +ASM_START + mov ax, ss +ASM_END +} + +#ifdef DEBUG +void unimplemented() +{ + printf("--> Unimplemented\n"); +} + +void unknown() +{ + printf("--> Unknown int10\n"); +} +#endif + +// -------------------------------------------------------------------------------------------- +#if defined(USE_BX_INFO) || defined(DEBUG) || defined(CIRRUS_DEBUG) +void printf(s) + Bit8u *s; +{ + Bit8u c, format_char; + Boolean in_format; + unsigned format_width, i; + Bit16u *arg_ptr; + Bit16u arg_seg, arg, digit, nibble, shift_count; + + arg_ptr = &s; + arg_seg = get_SS(); + + in_format = 0; + format_width = 0; + + while (c = read_byte(0xc000, s)) { + if ( c == '%' ) { + in_format = 1; + format_width = 0; + } + else if (in_format) { + if ( (c>='0') && (c<='9') ) { + format_width = (format_width * 10) + (c - '0'); + } + else if (c == 'x') { + arg_ptr++; // increment to next arg + arg = read_word(arg_seg, arg_ptr); + if (format_width == 0) + format_width = 4; + i = 0; + digit = format_width - 1; + for (i=0; i<format_width; i++) { + nibble = (arg >> (4 * digit)) & 0x000f; + if (nibble <= 9) + outb(0x0500, nibble + '0'); + else + outb(0x0500, (nibble - 10) + 'A'); + digit--; + } + in_format = 0; + } + //else if (c == 'd') { + // in_format = 0; + // } + } + else { + outb(0x0500, c); + } + s ++; + } +} +#endif + +ASM_START + ; get LFB address from PCI + ; in - ax: PCI device vendor + ; out - ax: LFB address (high 16 bit) + ;; NOTE - may be called in protected mode +_pci_get_lfb_addr: + push bx + push cx + push dx + push eax + mov bx, ax + xor cx, cx + mov dl, #0x00 + call pci_read_reg + cmp ax, #0xffff + jz pci_get_lfb_addr_5 + pci_get_lfb_addr_3: + mov dl, #0x00 + call pci_read_reg + cmp ax, bx ;; check vendor + jz pci_get_lfb_addr_4 + add cx, #0x8 + cmp cx, #0x200 ;; search bus #0 and #1 + jb pci_get_lfb_addr_3 + pci_get_lfb_addr_5: + xor dx, dx ;; no LFB + jmp pci_get_lfb_addr_6 + pci_get_lfb_addr_4: + mov dl, #0x10 ;; I/O space #0 + call pci_read_reg + test ax, #0xfff1 + jnz pci_get_lfb_addr_5 + shr eax, #16 + mov dx, ax ;; LFB address + pci_get_lfb_addr_6: + pop eax + mov ax, dx + pop dx + pop cx + pop bx + ret + + ; read PCI register + ; in - cx: device/function + ; in - dl: register + ; out - eax: value +pci_read_reg: + mov eax, #0x00800000 + mov ax, cx + shl eax, #8 + mov al, dl + mov dx, #0xcf8 + out dx, eax + add dl, #4 + in eax, dx + ret +ASM_END + +#ifdef VBE +#include "vbe.c" +#endif + +#ifdef CIRRUS +#include "clext.c" +#endif + +// -------------------------------------------------------------------------------------------- + +ASM_START +;; DATA_SEG_DEFS_HERE +ASM_END + +ASM_START +.ascii "vgabios ends here" +.byte 0x00 +vgabios_end: +.byte 0xCB +;; BLOCK_STRINGS_BEGIN +ASM_END diff --git a/vgabios.h b/vgabios.h new file mode 100644 index 0000000..3ad4bae --- /dev/null +++ b/vgabios.h @@ -0,0 +1,47 @@ +#ifndef vgabios_h_included +#define vgabios_h_included + +/* Types */ +typedef unsigned char Bit8u; +typedef unsigned short Bit16u; +typedef unsigned long Bit32u; +typedef unsigned short Boolean; + +/* Defines */ + +#define SET_AL(val8) AX = ((AX & 0xff00) | (val8)) +#define SET_BL(val8) BX = ((BX & 0xff00) | (val8)) +#define SET_CL(val8) CX = ((CX & 0xff00) | (val8)) +#define SET_DL(val8) DX = ((DX & 0xff00) | (val8)) +#define SET_AH(val8) AX = ((AX & 0x00ff) | ((val8) << 8)) +#define SET_BH(val8) BX = ((BX & 0x00ff) | ((val8) << 8)) +#define SET_CH(val8) CX = ((CX & 0x00ff) | ((val8) << 8)) +#define SET_DH(val8) DX = ((DX & 0x00ff) | ((val8) << 8)) + +#define GET_AL() ( AX & 0x00ff ) +#define GET_BL() ( BX & 0x00ff ) +#define GET_CL() ( CX & 0x00ff ) +#define GET_DL() ( DX & 0x00ff ) +#define GET_AH() ( AX >> 8 ) +#define GET_BH() ( BX >> 8 ) +#define GET_CH() ( CX >> 8 ) +#define GET_DH() ( DX >> 8 ) + +#define SET_CF() FLAGS |= 0x0001 +#define CLEAR_CF() FLAGS &= 0xfffe +#define GET_CF() (FLAGS & 0x0001) + +#define SET_ZF() FLAGS |= 0x0040 +#define CLEAR_ZF() FLAGS &= 0xffbf +#define GET_ZF() (FLAGS & 0x0040) + +#define SCROLL_DOWN 0 +#define SCROLL_UP 1 +#define NO_ATTR 2 +#define WITH_ATTR 3 + +#define SCREEN_SIZE(x,y) (((x*y*2)|0x00ff)+1) +#define SCREEN_MEM_START(x,y,p) ((((x*y*2)|0x00ff)+1)*p) +#define SCREEN_IO_START(x,y,p) ((((x*y)|0x00ff)+1)*p) + +#endif diff --git a/vgafonts.h b/vgafonts.h new file mode 100644 index 0000000..0c213e6 --- /dev/null +++ b/vgafonts.h @@ -0,0 +1,784 @@ +/* + * These fonts come from ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip + * The package is (c) by Joseph Gil + * The individual fonts are public domain + */ +static Bit8u vgafont8[256*8]= +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, + 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, + 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, + 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, + 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c, + 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, + 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, + 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, + 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, + 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, + 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, + 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0, + 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, + 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99, + 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, + 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, + 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, + 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, + 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, + 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff, + 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, + 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, + 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, + 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, + 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, + 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, + 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, + 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, + 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, + 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, + 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, + 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, + 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, + 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, + 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, + 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, + 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00, + 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, + 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00, + 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, + 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, + 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00, + 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, + 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, + 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, + 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, + 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, + 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, + 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, + 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, + 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00, + 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, + 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, + 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, + 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00, + 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, + 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, + 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, + 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, + 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, + 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, + 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00, + 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, + 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00, + 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00, + 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, + 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, + 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, + 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00, + 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, + 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, + 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, + 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, + 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00, + 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, + 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, + 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, + 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00, + 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, + 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, + 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00, + 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, + 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00, + 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, + 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00, + 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, + 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00, + 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, + 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78, + 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00, + 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38, + 0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00, + 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, + 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, + 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, + 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00, + 0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00, + 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00, + 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00, + 0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, + 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00, + 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, + 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18, + 0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00, + 0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30, + 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7, + 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70, + 0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, + 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, + 0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00, + 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00, + 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, + 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, + 0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, + 0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f, + 0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03, + 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00, + 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00, + 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, + 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, + 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, + 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00, + 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0, + 0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, + 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, + 0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00, + 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0, + 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00, + 0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc, + 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00, + 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00, + 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, + 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0, + 0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00, + 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, + 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, + 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00, + 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, + 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00, + 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, + 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, + 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, + 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, + 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, + 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static Bit8u vgafont14[256*14]= +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x06, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x66, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe6, 0x66, 0x6c, 0x6c, 0x78, 0x6c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x7c, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x70, 0x1c, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x66, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, + 0x00, 0xc6, 0xc6, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, + 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, + 0x00, 0xc0, 0xc0, 0xc6, 0xcc, 0xd8, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfc, 0xc6, 0xc6, 0xfc, 0xc0, 0xc0, 0x40, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static Bit8u vgafont16[256*16]= +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, + 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static Bit8u vgafont14alt[1]={0x00}; +static Bit8u vgafont16alt[1]={0x00}; diff --git a/vgatables.h b/vgatables.h new file mode 100644 index 0000000..3ac96bb --- /dev/null +++ b/vgatables.h @@ -0,0 +1,622 @@ +/* + * + * BIOS Memory + * + */ +#define BIOSMEM_SEG 0x40 + +#define BIOSMEM_INITIAL_MODE 0x10 +#define BIOSMEM_CURRENT_MODE 0x49 +#define BIOSMEM_NB_COLS 0x4A +#define BIOSMEM_PAGE_SIZE 0x4C +#define BIOSMEM_CURRENT_START 0x4E +#define BIOSMEM_CURSOR_POS 0x50 +#define BIOSMEM_CURSOR_TYPE 0x60 +#define BIOSMEM_CURRENT_PAGE 0x62 +#define BIOSMEM_CRTC_ADDRESS 0x63 +#define BIOSMEM_CURRENT_MSR 0x65 +#define BIOSMEM_CURRENT_PAL 0x66 +#define BIOSMEM_NB_ROWS 0x84 +#define BIOSMEM_CHAR_HEIGHT 0x85 +#define BIOSMEM_VIDEO_CTL 0x87 +#define BIOSMEM_SWITCHES 0x88 +#define BIOSMEM_MODESET_CTL 0x89 +#define BIOSMEM_DCC_INDEX 0x8A +#define BIOSMEM_VS_POINTER 0xA8 +#define BIOSMEM_VBE_FLAG 0xB9 +#define BIOSMEM_VBE_MODE 0xBA + + +/* + * + * VGA registers + * + */ +#define VGAREG_ACTL_ADDRESS 0x3c0 +#define VGAREG_ACTL_WRITE_DATA 0x3c0 +#define VGAREG_ACTL_READ_DATA 0x3c1 + +#define VGAREG_INPUT_STATUS 0x3c2 +#define VGAREG_WRITE_MISC_OUTPUT 0x3c2 +#define VGAREG_VIDEO_ENABLE 0x3c3 +#define VGAREG_SEQU_ADDRESS 0x3c4 +#define VGAREG_SEQU_DATA 0x3c5 + +#define VGAREG_PEL_MASK 0x3c6 +#define VGAREG_DAC_STATE 0x3c7 +#define VGAREG_DAC_READ_ADDRESS 0x3c7 +#define VGAREG_DAC_WRITE_ADDRESS 0x3c8 +#define VGAREG_DAC_DATA 0x3c9 + +#define VGAREG_READ_FEATURE_CTL 0x3ca +#define VGAREG_READ_MISC_OUTPUT 0x3cc + +#define VGAREG_GRDC_ADDRESS 0x3ce +#define VGAREG_GRDC_DATA 0x3cf + +#define VGAREG_MDA_CRTC_ADDRESS 0x3b4 +#define VGAREG_MDA_CRTC_DATA 0x3b5 +#define VGAREG_VGA_CRTC_ADDRESS 0x3d4 +#define VGAREG_VGA_CRTC_DATA 0x3d5 + +#define VGAREG_MDA_WRITE_FEATURE_CTL 0x3ba +#define VGAREG_VGA_WRITE_FEATURE_CTL 0x3da +#define VGAREG_ACTL_RESET 0x3da + +#define VGAREG_MDA_MODECTL 0x3b8 +#define VGAREG_CGA_MODECTL 0x3d8 +#define VGAREG_CGA_PALETTE 0x3d9 + +/* Video memory */ +#define VGAMEM_GRAPH 0xA000 +#define VGAMEM_CTEXT 0xB800 +#define VGAMEM_MTEXT 0xB000 + +/* + * + * Tables of default values for each mode + * + */ +#define MODE_MAX 15 +#define TEXT 0x00 +#define GRAPH 0x01 + +#define CTEXT 0x00 +#define MTEXT 0x01 +#define CGA 0x02 +#define PLANAR1 0x03 +#define PLANAR4 0x04 +#define LINEAR8 0x05 + +// for SVGA +#define LINEAR15 0x10 +#define LINEAR16 0x11 +#define LINEAR24 0x12 +#define LINEAR32 0x13 + +typedef struct +{Bit8u svgamode; + Bit8u class; /* TEXT, GRAPH */ + Bit8u memmodel; /* CTEXT,MTEXT,CGA,PL1,PL2,PL4,P8,P15,P16,P24,P32 */ + Bit8u pixbits; + Bit16u sstart; + Bit8u pelmask; + Bit8u dacmodel; /* 0 1 2 3 */ +} VGAMODES; + +static VGAMODES vga_modes[MODE_MAX+1]= +{//mode class model bits sstart pelm dac + {0x00, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02}, + {0x01, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02}, + {0x02, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02}, + {0x03, TEXT, CTEXT, 4, 0xB800, 0xFF, 0x02}, + {0x04, GRAPH, CGA, 2, 0xB800, 0xFF, 0x01}, + {0x05, GRAPH, CGA, 2, 0xB800, 0xFF, 0x01}, + {0x06, GRAPH, CGA, 1, 0xB800, 0xFF, 0x01}, + {0x07, TEXT, MTEXT, 4, 0xB000, 0xFF, 0x00}, + {0x0D, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x01}, + {0x0E, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x01}, + {0x0F, GRAPH, PLANAR1, 1, 0xA000, 0xFF, 0x00}, + {0x10, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x02}, + {0x11, GRAPH, PLANAR1, 1, 0xA000, 0xFF, 0x02}, + {0x12, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x02}, + {0x13, GRAPH, LINEAR8, 8, 0xA000, 0xFF, 0x03}, + {0x6A, GRAPH, PLANAR4, 4, 0xA000, 0xFF, 0x02} +}; + +/* convert index in vga_modes[] to index in video_param_table[] */ +static Bit8u line_to_vpti[MODE_MAX+1]={ + 0x17, 0x17, 0x18, 0x18, 0x04, 0x05, 0x06, 0x07, + 0x0d, 0x0e, 0x11, 0x12, 0x1a, 0x1b, 0x1c, 0x1d, +}; + +/* Default Palette */ +#define DAC_MAX_MODEL 3 + +static Bit8u dac_regs[DAC_MAX_MODEL+1]= +{0x3f,0x3f,0x3f,0xff}; + +/* standard BIOS Video Parameter Table */ +typedef struct { + Bit8u twidth; + Bit8u theightm1; + Bit8u cheight; + Bit8u slength_l; + Bit8u slength_h; + Bit8u sequ_regs[4]; + Bit8u miscreg; + Bit8u crtc_regs[25]; + Bit8u actl_regs[20]; + Bit8u grdc_regs[9]; +} VideoParamTableEntry; + +static VideoParamTableEntry video_param_table[30] = { +{ + /* index=0x00 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x01 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x02 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x03 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x04 vga mode 0x04 */ + 40, 24, 8, 0x00, 0x08, /* tw, th-1, ch, slength */ + 0x09, 0x03, 0x00, 0x02, /* sequ_regs */ + 0x63, /* miscreg */ + 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, + 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, + 0xff, /* crtc_regs */ + 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x01, 0x00, 0x03, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x05 vga mode 0x05 */ + 40, 24, 8, 0x00, 0x08, /* tw, th-1, ch, slength */ + 0x09, 0x03, 0x00, 0x02, /* sequ_regs */ + 0x63, /* miscreg */ + 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, + 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, + 0xff, /* crtc_regs */ + 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x01, 0x00, 0x03, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x06 vga mode 0x06 */ + 80, 24, 8, 0x00, 0x10, /* tw, th-1, ch, slength */ + 0x01, 0x01, 0x00, 0x06, /* sequ_regs */ + 0x63, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, + 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2, + 0xff, /* crtc_regs */ + 0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, + 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, + 0x01, 0x00, 0x01, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x07 vga mode 0x07 */ + 80, 24, 16, 0x00, 0x10, /* tw, th-1, ch, slength */ + 0x00, 0x03, 0x00, 0x02, /* sequ_regs */ + 0x66, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, + 0xff, /* crtc_regs */ + 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x0e, 0x00, 0x0f, 0x08, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x08 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x09 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x0a no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x0b no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x0c no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x0d vga mode 0x0d */ + 40, 24, 8, 0x00, 0x20, /* tw, th-1, ch, slength */ + 0x09, 0x0f, 0x00, 0x06, /* sequ_regs */ + 0x63, /* miscreg */ + 0x2d, 0x27, 0x28, 0x90, 0x2b, 0x80, 0xbf, 0x1f, + 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3, + 0xff, /* crtc_regs */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x0e vga mode 0x0e */ + 80, 24, 8, 0x00, 0x40, /* tw, th-1, ch, slength */ + 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ + 0x63, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, + 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3, + 0xff, /* crtc_regs */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x0f no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x10 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x11 vga mode 0x0f */ + 80, 24, 14, 0x00, 0x80, /* tw, th-1, ch, slength */ + 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ + 0xa3, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, + 0xff, /* crtc_regs */ + 0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x12 vga mode 0x10 */ + 80, 24, 14, 0x00, 0x80, /* tw, th-1, ch, slength */ + 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ + 0xa3, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0x85, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, + 0xff, /* crtc_regs */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x13 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x14 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x15 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x16 no mode defined */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}, +{ + /* index=0x17 vga mode 0x01 */ + 40, 24, 16, 0x00, 0x08, /* tw, th-1, ch, slength */ + 0x08, 0x03, 0x00, 0x02, /* sequ_regs */ + 0x67, /* miscreg */ + 0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f, + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3, + 0xff, /* crtc_regs */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x0c, 0x00, 0x0f, 0x08, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x18 vga mode 0x03 */ + 80, 24, 16, 0x00, 0x10, /* tw, th-1, ch, slength */ + 0x00, 0x03, 0x00, 0x02, /* sequ_regs */ + 0x67, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, + 0xff, /* crtc_regs */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x0c, 0x00, 0x0f, 0x08, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x19 vga mode 0x07 */ + 80, 24, 16, 0x00, 0x10, /* tw, th-1, ch, slength */ + 0x00, 0x03, 0x00, 0x02, /* sequ_regs */ + 0x66, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, + 0xff, /* crtc_regs */ + 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x0e, 0x00, 0x0f, 0x08, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x1a vga mode 0x11 */ + 80, 29, 16, 0x00, 0x00, /* tw, th-1, ch, slength */ + 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ + 0xe3, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, + 0xff, /* crtc_regs */ + 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, + 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, + 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x1b vga mode 0x12 */ + 80, 29, 16, 0x00, 0x00, /* tw, th-1, ch, slength */ + 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ + 0xe3, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, + 0xff, /* crtc_regs */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x1c vga mode 0x13 */ + 40, 24, 8, 0x00, 0x00, /* tw, th-1, ch, slength */ + 0x01, 0x0f, 0x00, 0x0e, /* sequ_regs */ + 0x63, /* miscreg */ + 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, + 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3, + 0xff, /* crtc_regs */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x41, 0x00, 0x0f, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff, /* grdc_regs */ +}, +{ + /* index=0x1d vga mode 0x6a */ + 100, 36, 16, 0x00, 0x00, /* tw, th-1, ch, slength */ + 0x01, 0x0f, 0x00, 0x06, /* sequ_regs */ + 0xe3, /* miscreg */ + 0x7f, 0x63, 0x63, 0x83, 0x6b, 0x1b, 0x72, 0xf0, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x59, 0x8d, 0x57, 0x32, 0x00, 0x57, 0x73, 0xe3, + 0xff, /* crtc_regs */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x01, 0x00, 0x0f, 0x00, /* actl_regs */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* grdc_regs */ +}, +}; + +/* Mono */ +static Bit8u palette0[63+1][3]= +{ + 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, + 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, + 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, + 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, + 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, + 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, + 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, 0x2a,0x2a,0x2a, + 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f, 0x3f,0x3f,0x3f +}; + +static Bit8u palette1[63+1][3]= +{ + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f +}; + +static Bit8u palette2[63+1][3]= +{ + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a, + 0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f, 0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f, + 0x00,0x15,0x00, 0x00,0x15,0x2a, 0x00,0x3f,0x00, 0x00,0x3f,0x2a, 0x2a,0x15,0x00, 0x2a,0x15,0x2a, 0x2a,0x3f,0x00, 0x2a,0x3f,0x2a, + 0x00,0x15,0x15, 0x00,0x15,0x3f, 0x00,0x3f,0x15, 0x00,0x3f,0x3f, 0x2a,0x15,0x15, 0x2a,0x15,0x3f, 0x2a,0x3f,0x15, 0x2a,0x3f,0x3f, + 0x15,0x00,0x00, 0x15,0x00,0x2a, 0x15,0x2a,0x00, 0x15,0x2a,0x2a, 0x3f,0x00,0x00, 0x3f,0x00,0x2a, 0x3f,0x2a,0x00, 0x3f,0x2a,0x2a, + 0x15,0x00,0x15, 0x15,0x00,0x3f, 0x15,0x2a,0x15, 0x15,0x2a,0x3f, 0x3f,0x00,0x15, 0x3f,0x00,0x3f, 0x3f,0x2a,0x15, 0x3f,0x2a,0x3f, + 0x15,0x15,0x00, 0x15,0x15,0x2a, 0x15,0x3f,0x00, 0x15,0x3f,0x2a, 0x3f,0x15,0x00, 0x3f,0x15,0x2a, 0x3f,0x3f,0x00, 0x3f,0x3f,0x2a, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f +}; + +static Bit8u palette3[256][3]= +{ + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x15,0x00, 0x2a,0x2a,0x2a, + 0x15,0x15,0x15, 0x15,0x15,0x3f, 0x15,0x3f,0x15, 0x15,0x3f,0x3f, 0x3f,0x15,0x15, 0x3f,0x15,0x3f, 0x3f,0x3f,0x15, 0x3f,0x3f,0x3f, + 0x00,0x00,0x00, 0x05,0x05,0x05, 0x08,0x08,0x08, 0x0b,0x0b,0x0b, 0x0e,0x0e,0x0e, 0x11,0x11,0x11, 0x14,0x14,0x14, 0x18,0x18,0x18, + 0x1c,0x1c,0x1c, 0x20,0x20,0x20, 0x24,0x24,0x24, 0x28,0x28,0x28, 0x2d,0x2d,0x2d, 0x32,0x32,0x32, 0x38,0x38,0x38, 0x3f,0x3f,0x3f, + 0x00,0x00,0x3f, 0x10,0x00,0x3f, 0x1f,0x00,0x3f, 0x2f,0x00,0x3f, 0x3f,0x00,0x3f, 0x3f,0x00,0x2f, 0x3f,0x00,0x1f, 0x3f,0x00,0x10, + 0x3f,0x00,0x00, 0x3f,0x10,0x00, 0x3f,0x1f,0x00, 0x3f,0x2f,0x00, 0x3f,0x3f,0x00, 0x2f,0x3f,0x00, 0x1f,0x3f,0x00, 0x10,0x3f,0x00, + 0x00,0x3f,0x00, 0x00,0x3f,0x10, 0x00,0x3f,0x1f, 0x00,0x3f,0x2f, 0x00,0x3f,0x3f, 0x00,0x2f,0x3f, 0x00,0x1f,0x3f, 0x00,0x10,0x3f, + 0x1f,0x1f,0x3f, 0x27,0x1f,0x3f, 0x2f,0x1f,0x3f, 0x37,0x1f,0x3f, 0x3f,0x1f,0x3f, 0x3f,0x1f,0x37, 0x3f,0x1f,0x2f, 0x3f,0x1f,0x27, + + 0x3f,0x1f,0x1f, 0x3f,0x27,0x1f, 0x3f,0x2f,0x1f, 0x3f,0x37,0x1f, 0x3f,0x3f,0x1f, 0x37,0x3f,0x1f, 0x2f,0x3f,0x1f, 0x27,0x3f,0x1f, + 0x1f,0x3f,0x1f, 0x1f,0x3f,0x27, 0x1f,0x3f,0x2f, 0x1f,0x3f,0x37, 0x1f,0x3f,0x3f, 0x1f,0x37,0x3f, 0x1f,0x2f,0x3f, 0x1f,0x27,0x3f, + 0x2d,0x2d,0x3f, 0x31,0x2d,0x3f, 0x36,0x2d,0x3f, 0x3a,0x2d,0x3f, 0x3f,0x2d,0x3f, 0x3f,0x2d,0x3a, 0x3f,0x2d,0x36, 0x3f,0x2d,0x31, + 0x3f,0x2d,0x2d, 0x3f,0x31,0x2d, 0x3f,0x36,0x2d, 0x3f,0x3a,0x2d, 0x3f,0x3f,0x2d, 0x3a,0x3f,0x2d, 0x36,0x3f,0x2d, 0x31,0x3f,0x2d, + 0x2d,0x3f,0x2d, 0x2d,0x3f,0x31, 0x2d,0x3f,0x36, 0x2d,0x3f,0x3a, 0x2d,0x3f,0x3f, 0x2d,0x3a,0x3f, 0x2d,0x36,0x3f, 0x2d,0x31,0x3f, + 0x00,0x00,0x1c, 0x07,0x00,0x1c, 0x0e,0x00,0x1c, 0x15,0x00,0x1c, 0x1c,0x00,0x1c, 0x1c,0x00,0x15, 0x1c,0x00,0x0e, 0x1c,0x00,0x07, + 0x1c,0x00,0x00, 0x1c,0x07,0x00, 0x1c,0x0e,0x00, 0x1c,0x15,0x00, 0x1c,0x1c,0x00, 0x15,0x1c,0x00, 0x0e,0x1c,0x00, 0x07,0x1c,0x00, + 0x00,0x1c,0x00, 0x00,0x1c,0x07, 0x00,0x1c,0x0e, 0x00,0x1c,0x15, 0x00,0x1c,0x1c, 0x00,0x15,0x1c, 0x00,0x0e,0x1c, 0x00,0x07,0x1c, + + 0x0e,0x0e,0x1c, 0x11,0x0e,0x1c, 0x15,0x0e,0x1c, 0x18,0x0e,0x1c, 0x1c,0x0e,0x1c, 0x1c,0x0e,0x18, 0x1c,0x0e,0x15, 0x1c,0x0e,0x11, + 0x1c,0x0e,0x0e, 0x1c,0x11,0x0e, 0x1c,0x15,0x0e, 0x1c,0x18,0x0e, 0x1c,0x1c,0x0e, 0x18,0x1c,0x0e, 0x15,0x1c,0x0e, 0x11,0x1c,0x0e, + 0x0e,0x1c,0x0e, 0x0e,0x1c,0x11, 0x0e,0x1c,0x15, 0x0e,0x1c,0x18, 0x0e,0x1c,0x1c, 0x0e,0x18,0x1c, 0x0e,0x15,0x1c, 0x0e,0x11,0x1c, + 0x14,0x14,0x1c, 0x16,0x14,0x1c, 0x18,0x14,0x1c, 0x1a,0x14,0x1c, 0x1c,0x14,0x1c, 0x1c,0x14,0x1a, 0x1c,0x14,0x18, 0x1c,0x14,0x16, + 0x1c,0x14,0x14, 0x1c,0x16,0x14, 0x1c,0x18,0x14, 0x1c,0x1a,0x14, 0x1c,0x1c,0x14, 0x1a,0x1c,0x14, 0x18,0x1c,0x14, 0x16,0x1c,0x14, + 0x14,0x1c,0x14, 0x14,0x1c,0x16, 0x14,0x1c,0x18, 0x14,0x1c,0x1a, 0x14,0x1c,0x1c, 0x14,0x1a,0x1c, 0x14,0x18,0x1c, 0x14,0x16,0x1c, + 0x00,0x00,0x10, 0x04,0x00,0x10, 0x08,0x00,0x10, 0x0c,0x00,0x10, 0x10,0x00,0x10, 0x10,0x00,0x0c, 0x10,0x00,0x08, 0x10,0x00,0x04, + 0x10,0x00,0x00, 0x10,0x04,0x00, 0x10,0x08,0x00, 0x10,0x0c,0x00, 0x10,0x10,0x00, 0x0c,0x10,0x00, 0x08,0x10,0x00, 0x04,0x10,0x00, + + 0x00,0x10,0x00, 0x00,0x10,0x04, 0x00,0x10,0x08, 0x00,0x10,0x0c, 0x00,0x10,0x10, 0x00,0x0c,0x10, 0x00,0x08,0x10, 0x00,0x04,0x10, + 0x08,0x08,0x10, 0x0a,0x08,0x10, 0x0c,0x08,0x10, 0x0e,0x08,0x10, 0x10,0x08,0x10, 0x10,0x08,0x0e, 0x10,0x08,0x0c, 0x10,0x08,0x0a, + 0x10,0x08,0x08, 0x10,0x0a,0x08, 0x10,0x0c,0x08, 0x10,0x0e,0x08, 0x10,0x10,0x08, 0x0e,0x10,0x08, 0x0c,0x10,0x08, 0x0a,0x10,0x08, + 0x08,0x10,0x08, 0x08,0x10,0x0a, 0x08,0x10,0x0c, 0x08,0x10,0x0e, 0x08,0x10,0x10, 0x08,0x0e,0x10, 0x08,0x0c,0x10, 0x08,0x0a,0x10, + 0x0b,0x0b,0x10, 0x0c,0x0b,0x10, 0x0d,0x0b,0x10, 0x0f,0x0b,0x10, 0x10,0x0b,0x10, 0x10,0x0b,0x0f, 0x10,0x0b,0x0d, 0x10,0x0b,0x0c, + 0x10,0x0b,0x0b, 0x10,0x0c,0x0b, 0x10,0x0d,0x0b, 0x10,0x0f,0x0b, 0x10,0x10,0x0b, 0x0f,0x10,0x0b, 0x0d,0x10,0x0b, 0x0c,0x10,0x0b, + 0x0b,0x10,0x0b, 0x0b,0x10,0x0c, 0x0b,0x10,0x0d, 0x0b,0x10,0x0f, 0x0b,0x10,0x10, 0x0b,0x0f,0x10, 0x0b,0x0d,0x10, 0x0b,0x0c,0x10, + 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00 +}; + +static Bit8u static_functionality[0x10]= +{ + /* 0 */ 0xff, // All modes supported #1 + /* 1 */ 0xe0, // All modes supported #2 + /* 2 */ 0x0f, // All modes supported #3 + /* 3 */ 0x00, 0x00, 0x00, 0x00, // reserved + /* 7 */ 0x07, // 200, 350, 400 scan lines + /* 8 */ 0x02, // mamimum number of visible charsets in text mode + /* 9 */ 0x08, // total number of charset blocks in text mode + /* a */ 0xe7, // Change to add new functions + /* b */ 0x0c, // Change to add new functions + /* c */ 0x00, // reserved + /* d */ 0x00, // reserved + /* e */ 0x00, // Change to add new functions + /* f */ 0x00 // reserved +}; |