diff options
author | Steffen Winterfeldt <wfeldt@opensuse.org> | 2004-03-15 08:51:06 +0000 |
---|---|---|
committer | Steffen Winterfeldt <wfeldt@opensuse.org> | 2004-03-15 08:51:06 +0000 |
commit | 0de4ac28074290e470c2b55e26a0f4cdf232db5c (patch) | |
tree | bfecc1aabb297695e8377451f0944c43d45fa6c3 |
- created repository
69 files changed, 23404 insertions, 0 deletions
@@ -0,0 +1,341 @@ +---------------------------------------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1c48b35 --- /dev/null +++ b/Makefile @@ -0,0 +1,46 @@ +CC = gcc +CFLAGS = -g -Wall -O2 -fomit-frame-pointer +X11LIBS = /usr/X11/lib +THEMES = $(wildcard themes/*) +# LIBFILES = happysuse.mod system.inc + +.PHONY: all themes clean install + +all: bin2c mkbootmsg bincode getx11font addblack + +getx11font: getx11font.c + $(CC) $(CFLAGS) -L$(X11LIBS) $< -lX11 -o $@ + +mkbootmsg: mkbootmsg.c vocabulary.h bincode.h + $(CC) $(CFLAGS) $< -o $@ + +addblack: addblack.c + $(CC) $(CFLAGS) $< -o $@ + +bincode: bincode.asm vocabulary.inc modplay_defines.inc modplay.inc kroete.inc + nasm -f bin -O10 -o $@ -l $(@).lst $< + +bincode.h: bincode bin2c + ./bin2c bincode >bincode.h + +bin2c: bin2c.c + $(CC) $(CFLAGS) $< -o $@ + +vocabulary.inc: mk_vocabulary + ./mk_vocabulary -a >$@ + +vocabulary.h: mk_vocabulary + ./mk_vocabulary -c >$@ + +install: all + install -d -m 755 $(DESTDIR)/usr/sbin $(DESTDIR)/usr/share/gfxboot + install -m 755 mkbootmsg getx11font help2txt $(DESTDIR)/usr/sbin +# install -m 644 $(LIBFILES) $(DESTDIR)/usr/share/gfxboot + cp -a themes $(DESTDIR)/usr/share/gfxboot + +clean: themes + @rm -f mkbootmsg bincode getx11font addblack bincode.h bin2c *.lst vocabulary.inc vocabulary.h *~ + +themes: + @for i in $(THEMES) ; do make -C $$i BINDIR=../../ $(MAKECMDGOALS) ; done + @@ -0,0 +1,662 @@ +Overview +======== + + To make a graphical boot screen you need a PCX image and a config file. + Optionally you might want a font file, but that is not really necessary as + you can simply use standard BIOS fonts. + + The config file is actually a program written in a Postscript-like + language that is run right after the boot manager entered graphics mode. + You must program everything related to graphics output in it. That does + even include drawing the background picture and setting the palette. + + Font files have a special format. Create them using 'getx11font'. + + The font must not exceed a size of 32x32. + + If you have written a suitable config file, create a syslinux/lilo message file + using mkbootmsg: + + mkbootmsg -c my_boot_configfile gfx_bootmessage + + Debugging this config file is rather tedious. In doing so, 'mkbootmsg -v' + might give you some information. Or try the 'dtrace' command (see language + reference below). + +Language Reference +================== + + Comments start with '%' and extend to the end of line. + + To include some other source file, do: + + %% include file + + Numbers are always 32 bit signed integer. Numerical and string constants + are given in a C-like way (_not_ as in Postscript). Examples: + + 123 + 0x4567 + "Hi there\n" + '\033' + + But: chars have values in the range 0 ... 255. + + Logical operations return values of type 'bool'. They are _not_ identical + with integers. There are no pre-defines constants 'true' and 'false'. But + you can define them yourself if you need them, e.g.: '/true 0 0 eq def'. + + Variable/constants/function names can consist of everything except + whitespace. + + - Callback functions + Communication with lilo/syslinux is done via callback functions. You are + responsible to assign useful actions to these. + See config file examples for more documentation. + + o KeyEvent + Called if a key is pressed. + + o MenuInit + Should draw the boot menu. + + o InfoBoxInit + Show a message box (e.g. error messages). + + o InfoBoxDone + Hide the message box. + + o ProgressInit + Initialize the progress bar (not yet available in lilo). + + o ProgressDone + Hide the progress bar. + + o ProgressUpdate + Advance the progress bar. + + o PasswordInit + Show password dialog. + + o PasswordDone + Hide password dialog. + + o Timeout + Timeout counter; called every 18.3th second until the timeout occurs. + + o Timer + Called every 18.3th second regardless of timeout. + + - { + Start code definition. + + stack: ( ) --> ( proc_1 ) + + Example: + /f { 10 mul } def + + - } + Finish code definition. + + stack: ( ) --> ( ) + + Example: + /f { 10 mul } def + + - [ + Start of an array. + + stack: ( ) --> ( array_start ) + + Example: + [ 1 2 3 ] + + - ] + End of an array (completes an array definition). + + stack: ( array_start obj_1 obj_2 ... ) --> ( array_1 ) + % array_1[0] is obj_1, array_1[1] is obj_2, etc. + + Example: + [ 1 2 3 ] + + - abs + Absolute value. + + stack: ( int_1 ) --> ( int_2 ) % int_2 = abs(int_1) + + - add + + stack: ( int_1 int_2 ) --> ( int_3 ) % int_3 = int_1 + int_2 + stack: ( string_1 int_1 ) --> ( string_2 ) % string_2 = string_1 + int_1 + + - and + + stack: ( int_1 int_2 ) --> ( int_3 ) % int_3 = int_1 & int_2 + stack: ( bool_1 bool_2 ) --> ( bool_3 ) % bool_3 = bool_1 && bool_2 + + - array + Create an empty array. + + stack: ( int_1 ) --> ( array_1 ) + % array_1 is an array with int_1 elements + + - bootloader + + stack: ( ) --> ( int_1 ) + % int_1: 0 = lilo, 1 = syslinux + + - currentcolor + Returns current drawing color. + + stack: ( ) --> ( int_1 ) + + - currentfont + Returns current font. + + stack: ( ) --> ( int_1 ) + + - currentpoint + Return current cursor position. + + stack: ( ) --> ( int_1 int_2 ) + % int_1: x pos, int_2: y pos + + - def + Defines a word. + + stack: ( key value ) --> ( ) + % key is defined as value + + Examples: + % constants + /x 55 def + % functions + /f { 10 mul } def + + - div + + stack: ( int_1 int_2 ) --> ( int_3 ) % int_3 = int_1 / int_2 + + - dtrace + Turn on trace mode (cf. 'trace') and show debug info in the upper left + screen corner (might not be visible on some graphics cards). + + stack: ( ) --> ( ) + + - dup + Duplicate tos. + + stack: ( obj_1 ) --> ( obj_1 obj_1 ) + + - edit.done + Restore input field background. + + stack: ( array_1 ) --> ( ) + % for array_1, see edit.init + + - edit.hidecursor + Hide cursor in input field. + + stack: ( array_1 ) --> ( ) + % for array_1, see edit.init + + - edit.init + Setup and show an editable input field. + + stack: ( array_1 string_1 ) --> ( ) + % the input field is initialized with string_1. + % array_1 must be a 8-dimensional array: + % [ x_pos, y_pos, screen_area, text_buf, text_buf_size, 0, 0, 0 ] + % screen_area holds the background pixmap for the input field and + % indirectly determines the size of the field. See 'savescreen' on + % how to create such a pixmap. + % text_buf is a string and should be large enough to hold + % text_buf_size chars. + % The last 3 elements are needed internally. + + - edit.input + Do some input action. + + stack: ( array_1 int_1 ) --> ( ) + % for array_1, see edit.init + % int_1, bits 15-8: scancode; int_1, bits 7-0: ascii + + - edit.showcursor + Show cursor in input field. + + stack: ( array_1 ) --> ( ) + % for array_1, see edit.init + + - eq + Compare. + + stack: ( int_1 int_2 ) --> ( bool_1 ) % bool_1 = int_1 == int_2 + stack: ( string_1 string_2 ) --> ( bool_1 ) % bool_1 = string_1 eq string_2 + stack: ( obj_1 obj_2 ) --> ( bool_1 ) % bool_1 = true if obj_1 and obj_2 are identical + + - exch + Swap the top two stack elements. + + stack: ( obj_1 obj_2 ) --> ( obj_2 obj_1 ) + + - exit + Leave loop/repeat/for loops. + + stack: ( ) --> ( ) + Example: + % leave if counter == 56 + 0 1 100 { 56 eq { exit } if } for + + - fillmode + Set fillmode used by 'fillrect'. + + stack: ( int_1 int_2 int_3 ) --> ( ) + % int_3 == 0: copy + % int_3 == 1: add + % int_1, int_2 color values + + - fillrect + Fill a rectangle; drawing mode is set by 'fillmode'. + + stack: ( int_1 int_2 ) --> ( ) + % int_1: width, int_2: height. + + - fontsize + Returns current fontsize. + + stack: ( ) --> ( int_1 int_2 ) + % int_1: font width, int_2: font height + + - for + Typical 'for' loop. + + stack: ( int_1 int_2 int_3 proc_1 ) + % int_1: start value, int_2: step size, int_3: end value (inclusive) + % every time proc_1 is executed, the current counter is put + % on the stack + + Example: + 0 1 4 { } for + % leaves ( 0 1 2 3 4 ) on the stack + + - free + Free malloc'ed memory. + Note: memory management is not implemented. You must do it currently all + by yourself using 'malloc' and 'free'. Arrays defined via 'array' should + also be free'ed. It does not harm, however, to free objects that were not + malloc'ed ('free' does nothing, then). + + stack: ( string_1 ) --> ( ) + stack: ( array_1 ) --> ( ) + + - ge + Compare. + + stack: ( int_1 int_2 ) --> ( bool_1 ) % bool_1 = int_1 >= int_2 + stack: ( string_1 string_2 ) --> ( bool_1 ) % bool_1 = string_1 ge string_2 + + - get + Return a array/string element. + + stack: ( array_1 int_1 ) --> ( obj_1 ) % obj_1 = array_1[int_1] + stack: ( string_1 int_1 ) --> ( int_2 ) % int2 = string_1[int_1] + + - getpalette + Return palette values for a color. + + stack: ( int_1 ) --> ( int_2 ) + % int_1: color + % int_2: rgb value for color + % (bits 23-16 red, bits 15-8 green, bits 7-0 blue) + + - getpixel + Read pixel from current drawing position. + + stack: ( ) --> ( int_1 ) + + - gt + Compare. + + stack: ( int_1 int_2 ) --> ( bool_1 ) % bool_1 = int_1 > int_2 + stack: ( string_1 string_2 ) --> ( bool_1 ) % bool_1 = string_1 gt string_2 + + - if + Typical 'if'. + + stack: ( bool_1 proc_1 ) --> ( ) + % execute proc_1 if bool_1 is true + + Example: + 10 4 gt { "Greater!" show } if + + - ifelse + Typical 'if'/'else' + + stack: ( bool_1 proc_1 proc_2 ) + % execute proc_1 if bool_1 is true otherwise proc_2 + + Example: + 10 4 gt { "Greater!" } { "Smaller!" } show ifelse + + - image + Draw part of the image (image was given via '%% image ...'). + + stack: ( int_1 int_2 int_3 int_4 ) --> ( ) + % int_1, int_2: position in image + % int_3, int_4: width, height + + Example: + % redraw the whole screen + 0 0 moveto + 0 0 screen.size image + + - image.colors + Return number of image colors. + + stack: ( ) --> ( int_1 ) + + - le + Compare. + + stack: ( int_1 int_2 ) --> ( bool_1 ) % bool_1 = int_1 <= int_2 + stack: ( string_1 string_2 ) --> ( bool_1 ) % bool_1 = string_1 le string_2 + + - length + Return array/string size. + Note: returns the actual length of the (0 terminated) string, _not_ + the size of the memory area allocated for it. + + stack: ( array_1 ) --> ( int_1 ) + stack: ( string_1 ) --> ( int_1 ) + + - lineto + Draw a line. + + stack: ( int_1 int_2 ) + % int_1, int_2: x, y line end + + Example: + 0 0 moveto + 200 100 lineto + + - loadpalette + Activate the image palette. + + stack: ( ) --> ( ) + + - loop + Typical 'loop'. + + stack: ( proc_1 ) + % proc_1 is executed forever (use 'exit' to break leave it) + + Example: + % loop until x == 56 + /x 0 def { /x x 1 add def x 56 eq { exit } if } loop + + - lt + Compare. + + stack: ( int_1 int_2 ) --> ( bool_1 ) % bool_1 = int_1 < int_2 + stack: ( string_1 string_2 ) --> ( bool_1 ) % bool_1 = string_1 lt string_2 + + - malloc + Malloc some memory (cf. 'free'). + + stack: ( int_1 ) --> ( string_1 ) + % Note: string_1 is initialized with 0 + + - max + + stack: ( int_1 int_2 ) --> ( int_3 ) % int_3 = max(int_1, int_2) + + - min + + stack: ( int_1 int_2 ) --> ( int_3 ) % int_3 = min(int_1, int_2) + + - mod + + stack: ( int_1 int_2 ) --> ( int_3 ) % int_3 = int_1 mod int_2 + + - mod.load + Asssign mod file to player. + + stack: ( int_1 int_2 ) --> ( ) + % int_1: player (0 .. 3) + % int_2: mod file + + - mod.play + Play mod. + + stack: ( int_1 int_2 ) --> ( ) + % int_1: player (0 .. 3) + % int_2: start of song + + - mod.playsample + + stack: ( int_1 int_2 int_3 int_4 ) --> ( ) + % int_1: player (0 .. 3) + % int_2: channel number + % int_3: sample number + % int_4: pitch + + - moveto + Set current drawing position. + + stack ( int_1 int_2 ) --> ( ) + % int_1, int_2: x, y + + Example: + 200 100 moveto + "Hello" show + + - mul + + stack: ( int_1 int_2 ) --> ( int_3 ) % int_3 = int_1 * int_2 + + - ne + Compare. + + stack: ( int_1 int_2 ) --> ( bool_1 ) % bool_1 = int_1 != int_2 + stack: ( string_1 string_2 ) --> ( bool_1 ) % bool_1 = string_1 ne string_2 + stack: ( obj_1 obj_2 ) --> ( bool_1 ) % bool_1 = false if obj_1 and obj_2 are identical + + - neg + + stack: ( int_1 ) --> ( int_2 ) % int_2 = -int_1 + + - not + + stack: ( bool_1 ) --> ( bool_2 ) % bool_2 = !bool_1 + + - or + + stack: ( int_1 int_2 ) --> ( int_3 ) % int_3 = int_1 | int_2 + stack: ( bool_1 bool_2 ) --> ( bool_3 ) % bool_3 = bool_1 || bool_2 + + - over + + stack: ( obj_1 obj_2 ) --> ( obj_1 obj_2 obj_1 ) + + - pop + Remove tos. + + stack: ( obj_1 ) --> ( ) + + - put + Set a array/string element. + Note: string size is not checked! + + stack: ( array_1 int_1 obj_1 ) --> ( ) % array_1[int_1] = obj_1 + stack: ( string_1 int_1 int_2 ) --> ( ) % string_1[int_1] = int_2 + + - putpixel + Set a pixel. + + stack: ( ) --> () + + - repeat + Typical 'repeat'. + + stack: ( int_1 proc_1 ) + % run proc_1 int_1 times + + Example: + % print "XXXXX" + 5 { "X" show } repeat + + - restorescreen + Restore screen area. + + stack: ( string_1 ) --> ( ) + % string_1 should be created by 'savescreen' + + - return + Leave the current function. + + stack: ( ) --> ( ) + + - rmoveto + Set current drawing position relative to current position. + + stack ( int_1 int_2 ) --> ( ) + % int_1, int_2: x, y + + Example: + 200 100 rmoveto + "Hello" show + + - roll + Rotate stack elements. + + stack: ( obj_1 ... obj_n int_1 int_2 ) --> ( obj_1' ... obj_n' ) + % int_1: number of elements to rotate (== n) + % int_2: amount + % 1' = (1 + int_2) mod int_1 + % n' = (n + int_2) mod int_1 + + - rot + Rotate upper tree stack elements. + Equivalent to "3 -1 roll". + + - savescreen + Save a screen area. + + stack: ( int_1 int_2 ) --> ( string_1 ) + % int_1, int_2: width, height + % string_1 is automatically malloc'ed but must manually be free'ed + + - screen.size + Return screen size. + + stack: ( ) --> ( int_1 int_2 ) + % int_1, int_2: width, height + + - setcolor + Set drawing color. + + stack: ( int_1 ) --> ( ) + % int_1: color + + - setfont + Set text font. + + stack: ( int_1 ) --> ( ) + % int_1: font + + - setpalette + Set palette. + + stack: ( int_1 int_2 ) --> ( ) + % int_1: color + % int_2: rgb value, (bits 23-16 red, bits 15-8 green, bits 7-0 blue) + + - settintcolor + + stack: ( int_1 int_2 ) --> ( ) + % int_1: rgb value + + - settransparentcolor + Set transparent color for 'image' operator. + + stack: ( int_1 ) --> ( ) + % int_1: color + + - shl + + stack: ( int_1 int_2 ) --> ( int_3 ) % int_3 = int_1 << int_2 + + - show + Print text. + + stack: ( string_1 ) --> ( ); + % print string_1 + + - shr + + stack: ( int_1 int_2 ) --> ( int_3 ) % int_3 = int_1 >> int_2 + + - snprintf + C-style snprintf. + Note the reversed argument order! + + stack: ( obj_1 ... obj_n string_1 int_1 string_2 ) --> ( ) + + Example: + /buf 100 malloc def + 10 5 "Hi, %d > %d\n" 100 buf snprintf + % sets buf to "Hi, 10 > 5\n" + + - sound.done + Turn off sound completely. + + stack: ( ) --> ( ) + + - sound.getvolume + Return current volume. + + stack: ( ) --> ( int_1 ) + + - sound.setvolume + Set sound volume. + + stack: ( int_1 ) --> ( ) + % int_1: volume (0 .. 100) + + - strstr + Find string_2 in string_1. Returns the offset of string_2 + 1 or 0, if it + was not found. + + stack: ( string_1 string_2 ) --> ( int_1 ) + + Example: + "abcd" "c" strstr + % returns 3 + + - strsize + Returns the size of the string in pixel (using the current font). + + stack: ( string_1 ) --> ( int_1 int_2 ) + % int_1, int_2: width, height + + - sub + + stack: ( int_1 int_2 ) --> ( int_3 ) % int_3 = int_1 - int_2 + stack: ( string_1 int_1 ) --> ( string_2 ) % string_2 = string_1 - int_1 + + - tint + + stack: ( int_1 int_2 int_3 ) --> ( ) + + - trace + Enter single step mode. Waits for a keypress after every instruction. + Leave this mode by pressing Esc. + + stack: ( ) --> ( ) + + - xor + + stack: ( int_1 int_2 ) --> ( int_3 ) % int_3 = int_1 ^ int_2 + stack: ( bool_1 bool_2 ) --> ( bool_3 ) % bool_3 = bool_1 ^^ bool_2 + diff --git a/addblack.c b/addblack.c new file mode 100644 index 0000000..95e793f --- /dev/null +++ b/addblack.c @@ -0,0 +1,173 @@ +/* + * add black as color #0 to a pcx file + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <inttypes.h> +#include <ctype.h> + +typedef struct { + unsigned size; + unsigned char *data; + unsigned real_size; +} file_data_t; + +void help(void); +file_data_t read_file(char *name); +int is_pcx(file_data_t *fd); +void write_data(file_data_t *fd, char *name); +void add_data(file_data_t *d, void *buffer, unsigned size); +void add_black(file_data_t *new, file_data_t *old); + +file_data_t pcx_old = {}; +file_data_t pcx_new = {}; + +int main(int argc, char **argv) +{ + if(argc != 3) return 1; + + pcx_old = read_file(argv[1]); + + if(!is_pcx(&pcx_old)) return 2; + + add_black(&pcx_new, &pcx_old); + + write_data(&pcx_new, argv[2]); + + return 0; +} + + +file_data_t read_file(char *name) +{ + file_data_t fd = { }; + FILE *f; + + if(!name) return fd; + + f = fopen(name, "r"); + if(!f) { perror(name); return fd; } + + if(fseek(f, 0, SEEK_END)) { + perror(name); + exit(30); + } + + fd.size = fd.real_size = ftell(f); + + if(fseek(f, 0, SEEK_SET)) { + perror(name); + exit(30); + } + + if(fd.size) { + fd.data = malloc(fd.size); + if(!fd.data) { + fprintf(stderr, "malloc failed\n"); + exit(30); + } + } + + if(fread(fd.data, 1, fd.size, f) != fd.size) { + perror(name); + exit(30); + } + + fclose(f); + + return fd; +} + + +int is_pcx(file_data_t *fd) +{ + if(!fd->data || fd->size < 0x381) return 0; + if( + fd->data[0] != 10 || + fd->data[1] != 5 || + fd->data[2] != 1 || + fd->data[3] != 8 || + fd->data[fd->size - 0x301] != 12 + ) return 0; + + return 1; +} + + +void write_data(file_data_t *fd, char *name) +{ + FILE *f; + + if(!fd->size) return; + + f = strcmp(name, "-") ? fopen(name, "w") : stdout; + + if(!f) { + perror(name); + return; + } + + if(fwrite(fd->data, fd->size, 1, f) != 1) { + perror(name); exit(3); + } + + fclose(f); +} + + +void add_data(file_data_t *d, void *buffer, unsigned size) +{ + if(!size || !d || !buffer) return; + + if(d->size + size > d->real_size) { + d->real_size = d->size + size + 0x1000; + d->data = realloc(d->data, d->real_size); + if(!d->data) d->real_size = 0; + } + + if(d->size + size <= d->real_size) { + memcpy(d->data + d->size, buffer, size); + d->size += size; + } + else { + fprintf(stderr, "Oops, out of memory? Aborted.\n"); + exit(10); + } +} + + +void add_black(file_data_t *new, file_data_t *old) +{ + int i, size; + unsigned char black[4] = { 12, 0, 0, 0 }; + unsigned char *src = old->data + 0x80; + unsigned char c[1]; + + add_data(new, old->data, 0x80); + size = old->size - 0x381; + + for(i = 0; i < size; i++) { + if(src[i] < 0xbf) { + *c = src[i] + 1; + add_data(new, c, 1); + } + else if(src[i] == 0xbf) { + *c = 0xc1; + add_data(new, c, 1); + *c = 0xc0; + add_data(new, c, 1); + } + else { + add_data(new, src + i, 1); + i++; + *c = src[i] + 1; + add_data(new, c, 1); + } + } + + add_data(new, black, 4); + add_data(new, old->data + old->size - 0x300, 0x300 - 3); +} + diff --git a/bin/add_text b/bin/add_text new file mode 100755 index 0000000..61857c7 --- /dev/null +++ b/bin/add_text @@ -0,0 +1,54 @@ +#! /usr/bin/perl + +# add a new text to *.po files + +die "usage: add_text [-c comment] id text_line1 text_line2 ... \nexample:\n add_text MENU_LANG Language\n" if @ARGV < 2; + +if($ARGV[0] eq '-c') { + shift; + $comment = shift; +} + +$id = shift; +@texts = @ARGV; + +$id =~ s/^TXT_//; + +$_ = join '', @texts; + +push @l, "# $comment\n" if $comment; +push @l, "#. TXT_$id\n"; +push @l, "#, c-format\n" if /%/; + +if(@texts == 1) { + push @l, "msgid \"$texts[0]\"\n" +} +else { + push @l, "msgid \"\"\n"; + for (@texts) { push @l, "\"$_\"\n" } +} + +push @l, "msgstr \"\"\n"; +push @l, "\n"; + +print @l; + +print STDERR "Should this entry be added to all *.po files? [Y/n]\n"; + +$_ = <STDIN>; + +chomp; + +$_ = "\L$_"; + +exit unless $_ eq '' || $_ eq 'y'; + +print "ok\n"; + +for $f ("linuxrc.pot", <*.po>) { + if(open F, ">>$f") { + print F @l; + close F; + } +} + diff --git a/bin/po2h b/bin/po2h new file mode 100755 index 0000000..7184ebd --- /dev/null +++ b/bin/po2h @@ -0,0 +1,161 @@ +#! /usr/bin/perl + +# convert *.po files to *.txt files suitable for linuxrc +# usage: po2h file.po >file.h +# Note: en.po ist treated specially! + +sub read_texts; +sub join_msg; + +for $lang (@ARGV) { + $lang = 'en' if $lang eq 'linuxrc.pot'; + $lang =~ s/\.po$//; + read_texts $lang; +} + + +sub read_texts +{ + local $_; + + my ($lang, @f, $txt, $context, $t, $p, $ids, $file); + + $lang = shift; + + $file = "$lang.po"; + $file = 'linuxrc.pot' if $lang eq 'en'; + + if($lang eq 'en') { + $ids = 1; + } + + open F, $file; + @f = (<F>); + close F; + + $_ = $lang; + s/.*\///; + print "/*\n * This file is generated automatically. Editing it is pointless.\n */\n\n"; + print "static text_t txt_${_}_atm [] =\n{\n"; + + for (@f) { + if(/^\s*#\.\s*(TXT_\S+)/) { + if($txt) { + @msgstr = @msgid if $ids || join_msg(\@msgstr) eq ""; + printf "{ %-25s", "$txt,"; + $p = pop @msgstr; + for $t (@msgstr) { + printf "%s\n%-27s", $t, ""; + } + printf "%-56s},\n", $p; + } + + $txt = $1; + + push @txts, $txt; + + undef @msgid; + undef @msgstr; + undef $context; + next; + } + + next if /^\s*#.*|^\s*$/; + + if(/^\s*msgid\s*(\".*\")\s*$/) { + push @msgid, $1 unless $1 eq '""'; + $context = 1; + next; + } + + if(/^\s*msgstr\s*(\".*\")\s*$/) { + push @msgstr, $1 unless $1 eq '""'; + $context = 2; + next; + } + + if(/^\s*(\".*\")\s*$/) { + if($context == 1) { + push @msgid, $1; + } + elsif($context == 2) { + push @msgstr, $1; + } + else { + die "format oops in ${lang}.po: $_" + } + } + } + + if($txt) { + printf "{ %-25s", "$txt,"; + @msgstr = @msgid if $ids || join_msg(\@msgstr) eq ""; + $p = pop @msgstr; + for $t (@msgstr) { + printf "%s\n%-27s", $t, ""; + } + printf "%-56s}\n", $p; + } + + print "};\n"; + + if($ids) { + open W, ">text_textids.h"; + print W "/*\n * This file is generated automatically. Editing it is pointless.\n */\n\n"; + print W "enum textid_t {\n"; + $p = pop @txts; + for (@txts) { print W " $_,\n" } + print W " $p\n};\n"; + close W; + } + else { + open F, "text_textids.h"; + for (<F>) { + if(/\s+(TXT_.+?)(\s|,)/) { + $txt_ref{$1} = undef; + } + } + close F; + for (@txts) { + $txt_list{$_}++; + $txt_multi{$_} = 1 if $txt_list{$_} > 1; + } + for (@txts) { + $txt_unknown{$_} = 1 unless exists $txt_ref{$_}; + } + for (keys %txt_ref) { + $txt_miss{$_} = 1 unless exists $txt_list{$_}; + } + + if(defined(%txt_miss) || defined(%txt_unknown) || defined(%txt_multi)) { + print STDERR "$lang:\n"; + for (sort keys %txt_miss) { + print STDERR " missing: $_\n" + } + for (sort keys %txt_unknown) { + print STDERR " unknown: $_\n" + } + for (sort keys %txt_multi) { + print STDERR " multi: $_\n" + } + } + } + +} + + +sub join_msg +{ + local $_; + my ($s, $msg, $m); + + $msg = shift; + + for $s (@{$msg}) { + $_ = $s; + s/^\"(.*)\"$/$1/; + $m .= $_; + } + + return $m; +} diff --git a/bin/rm_text b/bin/rm_text new file mode 100755 index 0000000..c3a871e --- /dev/null +++ b/bin/rm_text @@ -0,0 +1,63 @@ +#! /usr/bin/perl + +# remove a text from *.po files + +sub drop; + +die "usage: rm_text id\n" if @ARGV != 1; + +$id = shift; +$id = "TXT_$id" unless $id =~ /^TXT_/; + +mkdir old, 0755; + +for $f ("linuxrc.pot", <*.po>) { + if(open F, $f) { + @f = <F>; + close F; + + ( $new, $old ) = drop @f; + if(open F, ">>old/$f") { + print F @$old; + close F; + + open F, ">$f"; + print F @$new; + close F; + } + } +} + + +sub drop +{ + local $_; + my (@f, @g, $drop_it, @d); + + for (@_) { + push @g, $_; + $drop_it = 1 if /^#\.\s*${id}\s*$/; + if(/^\s*$/) { + if($drop_it) { + push @d, @g; + } + else { + push @f, @g; + } + undef $drop_it; + undef @g; + } + } + + if(@g) { + if($drop_it) { + push @d, @g; + } + else { + push @f, @g; + } + } + + return ( \@f, \@d ); +} + diff --git a/bin/txt2po b/bin/txt2po new file mode 100755 index 0000000..59e3b21 --- /dev/null +++ b/bin/txt2po @@ -0,0 +1,179 @@ +#! /usr/bin/perl + +# convert old linuxrc *.txt files to *.po files + +sub read_texts; +sub join_msg; + +%pmap = ( + "brasil", "pt_BR", + "breton", "br", + "czech", "cs", + "dutch", "nl", + "english", "en", + "french", "fr", + "german", "de", + "greek", "el", + "hungarian", "hu", + "indonesia", "id", + "italian", "it", + "polish", "pl", + "portuguese", "pt", + "romanian", "ro", + "russian", "ru", + "slovak", "sk", + "spanish", "es" +); + +%po2lang = ( + "pt_BR", "Brasil", + "br", "Breton", + "cs", "Czech", + "nl", "Dutch", + "en", "LANGUAGE", + "fr", "French", + "de", "German", + "el", "Hellenic", + "hu", "Hungarian", + "id", "Indonesian", + "it", "Italian", + "pl", "Polish", + "pt", "Portugese", + "ro", "Romanian", + "ru", "Russian", + "sk", "Slovak", + "es", "Spanish" +); + +%po2charset = ( + "pt_BR", "iso-8859-1", + "br", "iso-8859-1", + "cs", "iso-8859-2", + "nl", "iso-8859-1", + "en", "ascii", + "fr", "iso-8859-1", + "de", "iso-8859-1", + "el", "iso-8859-7", + "hu", "iso-8859-2", + "id", "iso-8859-1", + "it", "iso-8859-1", + "pl", "iso-8859-2", + "pt", "iso-8859-1", + "ro", "iso-8859-2", + "ru", "koi8-r", + "sk", "iso-8859-2", + "es", "iso-8859-1" +); + +read_texts "english", 1; + +for $lang (@ARGV) { + $lang =~ s/\.txt$//; + read_texts $lang; +} + + +sub read_texts +{ + local $_; + + my ($lang, @f, %txt, $txt, $t, $ids); + + $lang = shift; + $ids = shift; + + open F, "${lang}.txt"; + @f = (<F>); + close F; + + for (@f) { + s/^\{?\s*//; + next if /^\}|^static|^\s*$/; + if(s/^(TXT_\S+?),\s*//) { + $txt = $1; + push @txts, $txt if $ids; + } + s/\s*(\},?)?\s*$//; + if(!/^\".*\"$/) { + die "format error in $lang.txt:\n$txt: >>$_<<\n" + } + push @{$txt{$txt}}, $_; +# print "$txt: >>$_<<\n" + } + + if($ids) { + %txt_en = %txt; + } + else { + $f = $pmap{$lang} ? "$pmap{$lang}.po" : "$lang.po"; + $f = "linuxrc.pot" if $lang eq 'english'; + open W, ">$f"; + + print W "# $po2lang{$pmap{$lang}} translations for linuxrc.\n"; + print W "# Copyright (C) 2001 SuSE GmbH.\n#\n"; + print W "msgid \"\"\n"; + print W "msgstr \"\"\n"; + print W "\"Project-Id-Version: linuxrc\\n\"\n"; + print W "\"PO-Revision-Date: 2001-08-03 12:00+0200\\n\"\n"; + print W "\"Last-Translator: FULL NAME <EMAIL\@ADDRESS>\\n\"\n"; + print W "\"Language-Team: $po2lang{$pmap{$lang}} <i18n\@suse.de>\\n\"\n"; + print W "\"MIME-Version: 1.0\\n\"\n"; + print W "\"Content-Type: text/plain; charset=$po2charset{$pmap{$lang}}\\n\"\n"; + print W "\"Content-Transfer-Encoding: 8bit\\n\"\n\n"; + + for (@txts) { + print W "#. $_\n"; + $x = join_msg $txt_en{$_}; + if($x =~ /%/) { + print W "#, c-format\n"; + } + + if(@{$txt_en{$_}} == 1) { + print W "msgid ${$txt_en{$_}}[0]\n" + } + else { + print W "msgid \"\"\n"; + for $t (@{$txt_en{$_}}) { + print W "$t\n" + } + } + + if(join_msg($txt{$_}) eq join_msg($txt_en{$_})) { + print W "msgstr \"\"\n"; + } + else { + if(@{$txt{$_}} == 1) { + print W "msgstr ${$txt{$_}}[0]\n" + } + else { + print W "msgstr \"\"\n"; + for $t (@{$txt{$_}}) { + print W "$t\n" + } + } + } + print W "\n" + } + close W; + } + +} + + +sub join_msg +{ + local $_; + my ($s, $msg, $m); + + $msg = shift; + + for $s (@{$msg}) { + $_ = $s; + s/^\"(.*)\"$/$1/; + $m .= $_; + } + + return $m; +} + + diff --git a/bin/txtinc b/bin/txtinc new file mode 100755 index 0000000..b6395b2 --- /dev/null +++ b/bin/txtinc @@ -0,0 +1,39 @@ +#! /usr/bin/perl + +# make some include files for linuxrc + +map { s/^(.*\/)?([^\/]+)\.po/$2/ } @ARGV; + +open W, ">text_inc.h"; +print W "/*\n * This file is generated automatically. Editing it is pointless.\n */\n\n"; +for (@ARGV) { + print W "#ifdef TRANS_$_\n#include \"po/$_.h\"\n#endif\n\n" +} +close W; + +open W, ">text_array.h"; +print W "/*\n * This file is generated automatically. Editing it is pointless.\n */\n\n"; +print W "static alltexts_t alltexts_arm [] = {\n"; +@list = ( "en", grep { $_ ne en} @ARGV); + +for ($i = 0 ; $i < @list; $i++) { + print W "#ifdef TRANS_$list[$i]\n"; + print W " { lang_$list[$i], LANG_ENTRY(txt_$list[$i]_atm) },\n"; + print W "#endif\n" +} +print W "};\n"; +close W; + +open W, ">text_langids.h"; +print W "/*\n * This file is generated automatically. Editing it is pointless.\n */\n\n"; +print W "/* lang_undef _must_ be 0 */\n\n"; +print W "enum langid_t {\n"; + +@list = ( "undef", @ARGV ); +for ($i = 0 ; $i < @list; $i++) { + print W " lang_$list[$i]"; + print W $i + 1 == @list ? "\n" : ",\n"; +} +print W "};\n"; +close W; + @@ -0,0 +1,37 @@ +#include <stdio.h> +#include <stdlib.h> + +int main(int argc, char **argv) +{ + int i, j = 0; + FILE *f; + + if(argc > 1) { + if(!(f = fopen(argv[1], "r"))) { + perror(argv[1]); + return 1; + } + } + else { + fprintf(stderr, "usage: bin2c file\n"); + return 2; + } + + printf("unsigned char %s_data[] = {\n", argv[1]); + + while((i = fgetc(f)) != EOF) { + i = i & 0xff; + if(!j++) { + printf(" "); + } + else { + printf(",%s", (j & 7) != 1 ? "" : "\n "); + } + printf(" 0x%02x", i); + } + + printf("\n};\n"); + + return 0; +} + diff --git a/bincode.asm b/bincode.asm new file mode 100644 index 0000000..935bed4 --- /dev/null +++ b/bincode.asm @@ -0,0 +1,10079 @@ +%define debug 1 + +%include "vocabulary.inc" +%include "modplay_defines.inc" + +; some type definitions from mkbootmsg.c +; struct file_header_t +fh_magic_id equ 0 +fh_version equ 4 +fh_res_1 equ 5 +fh_res_2 equ 6 +fh_file_entries equ 7 +fh_bincode equ 8 +fh_bincode_size equ 12 +fh_bincode_crc equ 16 +fh_dict equ 20 +fh_code equ 24 +fh_code_size equ 28 +sizeof_file_header_t equ 32 + + +; font file header definition +; struct font_header_t +foh_magic equ 0 +foh_entries equ 4 +foh_height equ 6 +foh_line_height equ 7 +sizeof_font_header_t equ 8 + +; char data header definition +; struct char_header_t +ch_ofs equ 0 +ch_c equ 2 +ch_size equ 4 +sizeof_char_header_t equ 8 ; must be 8, otherwise change find_char + +; struct file_raw_t +fi_raw_data equ 0 +fi_raw_size equ 4 +sizeof_file_raw_t equ 8 + +; struct playlist +pl_file equ 0 ; actually file index + 1 +pl_loop equ 1 +pl_res1 equ 2 +pl_res2 equ 3 +pl_start equ 4 +pl_current equ 8 +pl_end equ 12 +sizeof_playlist equ 16 +playlist_entries equ 4 + +; struct link +li_label equ 0 +li_text equ 2 +li_x equ 4 +li_row equ 6 +sizeof_link equ 8 ; search for 'sizeof_link'! +link_entries equ 64 + +; enum_type_t +t_none equ 0 +t_int equ 1 +t_unsigned equ 2 +t_bool equ 3 +t_string equ 4 +t_code equ 5 +t_ret equ 6 +t_prim equ 7 +t_sec equ 8 +t_dict_idx equ 9 +t_array equ 10 +t_end equ 11 +t_ptr equ 12 + +t_if equ t_code + 10h +t_loop equ t_code + 20h +t_repeat equ t_code + 30h +t_for equ t_code + 40h +t_forall equ t_code + 50h +t_exit equ t_code + 60h + + +param_stack_size equ 1000 +ret_stack_size equ 1000 + +; various error codes +pserr_ok equ 0 +pserr_nocode equ 1 +pserr_invalid_opcode equ 2 +pserr_pstack_underflow equ 3 +pserr_pstack_overflow equ 4 +pserr_rstack_underflow equ 5 +pserr_rstack_overflow equ 6 +pserr_invalid_dict equ 7 +pserr_wrong_arg_types equ 8 +pserr_div_by_zero equ 9 +pserr_invalid_rstack_entry equ 0ah +pserr_invalid_range equ 0bh +pserr_invalid_exit equ 0ch +pserr_invalid_image_size equ 0dh +pserr_no_memory equ 0eh +pserr_invalid_data equ 0fh +pserr_nop equ 10h +pserr_invalid_dict_entry equ 200h +pserr_invalid_prim equ 201h + +keyBS equ 08h +keyLeft equ 4bh ; scan code +keyRight equ 4dh ; scan code +keyHome equ 47h ; scan code +keyEnd equ 4fh ; scan code +keyDel equ 53h ; scan code + +max_text_rows equ 128 + + section .text + +; jmp table to interface functions +jt_init dw gfx_init +jt_done dw gfx_done +jt_input dw gfx_input +jt_menu_init dw gfx_menu_init +jt_infobox_init dw gfx_infobox_init +jt_infobox_done dw gfx_infobox_done +jt_progress_init dw gfx_progress_init +jt_progress_done dw gfx_progress_done +jt_progress_update dw gfx_progress_update +jt_progress_limit dw gfx_progress_limit +jt_password_init dw gfx_password_init +jt_password_done dw gfx_password_done + + align 4, db 0 +; the memory area we are working with +mem dd 0 ; (lin) data start address +mem_free dd 0 ; (lin) start of free area for malloc +mem_max dd 0 ; (lin) end address +mem_archive dd 0 ; (lin) archive start address (0 -> none), ends at mem_free + +vbe_buffer dd 0 ; (seg:ofs) buffer for vbe calls +vbe_mode_list dd 0 ; (seg:ofs) list with vbe modes +infobox_buffer dd 0 ; (lin) temp buffer for InfoBox messages + +pscode_start dd 0 ; (lin) +pscode_size dd 0 +pscode_instr dd 0 ; (lin) current instruction (rel. to pscode_start) +pscode_next_instr dd 0 ; (lin) next instruction +; for debugging only +pscode_next_break dd 0 ; (lin) break at this instruction +pscode_eval dd 0 ; opcode from exec instruction +pscode_error_arg_0 dd 0 +pscode_error_arg_1 dd 0 +pscode_arg dd 0 ; current arg +pscode_error dw 0 ; error code (if any) +pscode_type db 0 ; current instr type + + align 4, db 0 +dict dd 0 ; seg:ofs +dict_size dw 0 ; dict entries + +boot_cs dw 0 ; seg +boot_sysconfig dw 0 ; ofs + +pstack dd 0 ; (seg:ofs) +pstack_size dw 0 ; entries +pstack_ptr dw 0 +rstack dd 0 ; (seg:ofs) +rstack_size dw 0 ; entries +rstack_ptr dw 0 + + +image dd 0 ; (lin) current image +image_width dw 0 +image_height dw 0 +image_data dd 0 ; (seg:ofs) +image_pal dd 0 ; (seg:ofs) +image_type db 0 ; 0:no image, 1: pcx, 2:jpeg + +pcx_line_starts dd 0 ; (lin) table of line starts + +screen_width dw 0 +screen_height dw 0 +screen_line_len dd 0 + +setpixel dw setpixel_8 ; function that sets one pixel +setpixel_a dw setpixel_a_8 ; function that sets one pixel +setpixel_t dw setpixel_8 ; function that sets one pixel +setpixel_ta dw setpixel_a_8 ; function that sets one pixel +getpixel dw getpixel_8 ; function that gets one pixel + + +transp dd 0 ; transparency + +; 0..100h +brightness dw 100h + + align 4, db 0 +; current font description +font dd 0 ; (seg:ofs) to font header +font_entries dw 0 ; chars in font +font_height dw 0 +font_line_height dw 0 + +; current char description +chr_bitmap dw 0 ; ofs rel. to [font] +chr_x_ofs dw 0 +chr_y_ofs dw 0 +chr_real_width dw 0 +chr_real_height dw 0 +chr_width dw 0 + +utf8_buf times 8 db 0 + +; pointer to currently active palette (3*100h bytes) +gfx_pal dd 0 ; (seg:ofs) +; pointer to tmp area (3*100h bytes) +gfx_pal_tmp dd 0 ; (seg:ofs) +; number of fixed pal values +pals dw 0 + +; the current gfx mode +gfx_mode dw 3 +; != 0 if we're using a vbe mode (hi byte of gfx_mode) +vbe_active equ gfx_mode + 1 +pixel_bits db 0 ; pixel size (8 or 16) +color_bits db 0 ; color bits (8, 15 or 16) +pixel_bytes dd 0 ; pixel size in bytes + +; segment address of writeable window +window_seg_w dw 0 +; segment address of readable window +; if 0 -> gfx_window_seg_w is rw +window_seg_r dw 0 +; ganularity units per window +window_inc db 0 +; currently mapped window +mapped_window db 0 + +; cursor position +gfx_cur equ $ ; both x & y +gfx_cur_x dw 0 +gfx_cur_y dw 0 ; must follow gfx_cur_x +gfx_width dw 0 +gfx_height dw 0 +line_wrap dw 0 + +; clip region (incl) +clip_l dw 0 ; left, incl +clip_r dw 0 ; right, excl +clip_t dw 0 ; top, incl +clip_b dw 0 ; bottom, excl + +line_x0 dd 0 +line_y0 dd 0 +line_x1 dd 0 +line_y1 dd 0 +line_tmp dd 0 + + align 4, db 0 +gfx_color dd 0 ; current color +gfx_color0 dd 0 ; color #0 (normal color)) +gfx_color1 dd 0 ; color #1 (highlight color) +gfx_color2 dd 0 ; color #2 (link color) +gfx_color3 dd 0 ; color #3 (selected link color) +transparent_color dw -1 +char_eot dd 0 ; 'end of text' char +last_label dw 0 ; ofs, seg = [row_start_seg] +page_title dw 0 ; ofs, seg = [row_start_seg] +max_rows dw 0 ; max. number of text rows +cur_row dw 0 ; current text row (0 based) +cur_row2 dw 0 ; dto, only durig formatting +start_row dw 0 ; start row for text output +cur_link dw 0 ; link count +sel_link dw 0 ; selected link +txt_state db 0 ; bit 0: 1 = skip text + ; bit 1: 1 = text formatting only +run_idle db 0 + + align 2, db 0 +row_start_seg dw 0 +row_start_ofs times max_text_rows dw 0 + + ; note: link_list relies on row_start_seg +link_list times sizeof_link * link_entries db 0 + +; currently used tint color (call load_palette to make changes visible) +gfx_cs_tint_r db 0 +gfx_cs_tint_g db 0 +gfx_cs_tint_b db 0 +gfx_cs_r db 0 +gfx_cs_g db 0 +gfx_cs_b db 0 + + + ; max label size: 32 +label_buf times 35 db 0 + +; buffer for number conversions +num_buf times 23h db 0 +num_buf_end db 0 + +; temp data for printf +tmp_write_data times 10h dd 0 +tmp_write_num dw 0 +tmp_write_sig db 0 +tmp_write_cnt db 0 +tmp_write_pad db 0 + +pf_gfx db 0 +pf_gfx_err dw 0 + align 4, db 0 +pf_gfx_buf dd 0 +pf_gfx_max dd 0 +pf_gfx_cnt dd 0 + + align 4, db 0 +input_timeout_start dd 0 +input_timeout dd 0 + +progress_max dd 0 +progress_current dd 0 + +edit_x dw 0 +edit_y dw 0 +edit_width dw 0 +edit_height dw 0 +edit_bg dd 0 ; (seg:ofs) +edit_buf dd 0 ; (seg:ofs) +edit_buf_len dw 0 +edit_buf_ptr dw 0 +edit_cursor dw 0 +edit_shift dw 0 +edit_y_ofs dw 0 + +kbd_status dw 0 + + +sound_buf_size equ 8*1024 + + align 4, db 0 +sound_x dd 0 +sound_old_int8 dd 0 +sound_old_61 db 0 +sound_61 db 0 +sound_cnt0 dw 0 +sound_timer0 dw 0 +sound_timer1 dw 0 +sound_vol db 0 +sound_ok db 0 +sound_int_active db 0 +sound_playing db 0 +sound_sample dd 0 +sound_buf dd 0 ; (seg:ofs) +sound_start dw 0 ; rel. to sound_buf +sound_end dw 0 ; rel. to sound_buf +playlist times playlist_entries * sizeof_playlist db 0 +mod_buf dd 0 ; (seg:ofs) +int8_count dd 0 +cycles_per_tt dd 0 +cycles_per_int dd 0 +next_int dd 0,0 + + align 4, db 0 +; temporary vars +tmp_var_0 dd 0 +tmp_var_1 dd 0 +tmp_var_2 dd 0 +tmp_var_3 dd 0 + +; gdt for pm switch +pm_cs equ 8 +pm_ss equ 10h +pm_ds equ 18h +pm_es equ 20h + + align 4 +pm_gdt dw pm_gdt_size-1 ; gdt descriptor + dd 0 ; for lgdt instruction + dw 0 +pm_gdt_cs dd 0000ffffh ; 64k code segment + dd 00009b00h +pm_gdt_ss dd 0000ffffh ; 64k data segment + dd 00009300h +pm_gdt_ds dd 0000ffffh ; 64k data segment + dd 00009300h +pm_gdb_es dd 0000ffffh ; 4GB data segment, start at 0 + dd 008f9300h +pm_gdt_size equ $-pm_gdt + + +%if debug +; debug texts +dmsg_01 db 'Memory: %p - %p, img data at %p', 10, 0 +dmsg_02 db 'Image: %u x %u (real: %u x %u)', 10, 0 +dmsg_03 db 'addr 0x%05x, size 0x%05x+4, %s', 10, 0 +dmsg_04 db 'oops: 0x%05x > 0x%05x', 10, 0 +dmsg_05 db 'oops: 0 size block', 10, 0 +dmsg_06 db 'addr 0x%05x', 10, 0 +dmsg_07 db 'free', 0 +dmsg_08 db 'used', 0 +dmsg_09 db 'current dictionary', 10, 0 +dmsg_10 db ' %2u: type %u, val 0x%x', 10, 0 + +%endif + +single_step db 0 +show_debug_info db 0 + +hello db 10, 'Initializing gfx code...', 10, 0 +msg_10 db '|ip %4x: %8x.%x |', 10, 0 +msg_11 db '|%2x: %8x.%2x', 0 +msg_12 db '| : ', 0 +msg_13 db '/----pstk------------rstk-------\', 10, 0 +msg_14 db '|-------------------------------|', 10, 0 +msg_15 db '\-------------------------------/', 10, 0 +msg_16 db '|', 10, 0 +msg_17 db '|err %3x |', 10, 0 +msg_18 db '|err %3x: %8x |', 10, 0 +msg_19 db '|err %3x: %8x %8x |', 10, 0 +msg_20 db '|ip %4x: %8x.%x %8x.%x |', 10, 0 + + align 2, db 0 + ; prim_function entries + prim_jump_table + +; menu entry descriptor +menu_entries equ 0 +menu_default equ 2 ; seg:ofs +menu_ent_list equ 6 ; seg:ofs +menu_ent_size equ 10 +menu_arg_list equ 12 ; seg:ofs +menu_arg_size equ 16 +sizeof_menu_desc equ 18 + +; framebuffer mode list +fb_mode equ 0 ; word +fb_width equ 2 ; word +fb_height equ 4 ; word, must follow fb_width +fb_bits equ 6 ; byte +fb_ok equ 7 ; monitor supports it +sizeof_fb_entry equ 8 + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Some macros. +; +%macro pf_arg_uchar 2 + and dword [tmp_write_data + %1 * 4],byte 0 + mov [tmp_write_data + %1 * 4],%2 +%endmacro + +%macro pf_arg_ushort 2 + and word [tmp_write_data + %1 * 4 + 2],byte 0 + mov [tmp_write_data + %1 * 4],%2 +%endmacro + +%macro pf_arg_uint 2 + mov [tmp_write_data + %1 * 4],%2 +%endmacro + +%macro pf_arg_char 2 + push eax + movsx eax,%2 + mov [tmp_write_data + %1 * 4],eax + pop eax +%endmacro + +%macro pf_arg_short 2 + push eax + movsx eax,%2 + mov [tmp_write_data + %1 * 4],eax + pop eax +%endmacro + +%macro pf_arg_int 2 + mov [tmp_write_data + %1 * 4],%2 +%endmacro + +%macro lin2segofs 3 + push %1 + call lin2so + pop %3 + pop %2 +%endmacro + +%macro segofs2lin 3 + push %1 + push %2 + call so2lin + pop %3 +%endmacro + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Interface functions. +; +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Initialize something. +; +; eax memory start +; ebx free memory start +; ecx memory end +; dx boot loader code segment +; si gfx_sysconfig offset +; edi file archive start, if any (ends at ebx) +; +; return: +; CF error +; +gfx_init: + push fs + push es + push ds + + push cs + pop ds + + cld + + mov [mem],eax + mov [mem_free],ebx + mov [mem_max],ecx + mov [mem_archive],edi + mov [boot_cs],dx + mov [boot_sysconfig],si + + ; init malloc memory chain + + ; align 4 + mov eax,[mem_free] + add eax,3 + and eax,~3 + mov [mem_free],eax + + push eax + call lin2so + pop bx + pop es + mov edx,[mem_max] + sub edx,eax + mov [es:bx],edx + +%if debug + mov si,hello + call printf +%endif + + ; get initial keyboard state + push byte 0 + pop es + push word [es:417h] + pop word [kbd_status] + +%if debug + mov eax,[mem] + pf_arg_uint 0,eax + mov eax,[mem_max] + pf_arg_uint 1,eax + mov eax,[mem_free] + pf_arg_uint 2,eax + + mov si,dmsg_01 + call printf +%endif + + call dict_init + jc gfx_init_90 + + call stack_init + jc gfx_init_90 + + mov eax,[mem] + lin2segofs eax,es,si + add eax,[es:si+fh_code] + mov [pscode_start],eax + mov eax,[es:si+fh_code_size] + mov [pscode_size],eax + + ; now the ps interpreter is ready to run + + ; alloc memory for palette data + call pal_init + + mov eax,100h + call calloc + cmp eax,byte 1 + jc gfx_init_90 + mov [infobox_buffer],eax + + mov eax,200h + call calloc + cmp eax,byte 1 + jc gfx_init_90 + push eax + call lin2so + pop dword [vbe_buffer] + + mov eax,200h + call calloc + cmp eax,byte 1 + jc gfx_init_90 + push eax + call lin2so + pop dword [vbe_mode_list] + + ; ok, we've done it, now continue the setup + +%if 0 + call dump_malloc + call get_key +%endif + + ; run global code + xor eax,eax + mov [pstack_ptr],ax + mov [rstack_ptr],ax + call run_pscode + jc gfx_init_60 + + ; check for true/false on stack + ; (empty stack == true) + + xor cx,cx + call get_pstack_tos + jc gfx_init_80 + cmp dl,t_bool + jnz gfx_init_70 + cmp eax,byte 1 + jz gfx_init_90 + jmp gfx_init_70 + +gfx_init_60: + call ps_status_info + call get_key +gfx_init_70: + push cs + call gfx_done + stc + jmp gfx_init_90 +gfx_init_80: + clc + +gfx_init_90: + pop ds + pop es + pop fs + retf + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Do something. +gfx_done: + push fs + push es + push ds + + push cs + pop ds + cld + + call sound_done + + mov ax,3 + int 10h + + pop ds + pop es + pop fs + retf + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; [boot_cs]:di buffer ( 0 --> no buffer ) +; cx buffer size +; ax timeout value (0 --> no timeout) +; return: +; eax action (1, 2: textmode, boot) +; ebx selected menu entry (-1: none) +; +gfx_input: + push fs + push es + push ds + + push di + push cx + + push cs + pop ds + cld + + movzx eax,ax + mov [input_timeout],eax + mov [input_timeout_start],eax + + call clear_kbd_queue + +gfx_input_20: + call get_key_to + and dword [input_timeout],byte 0 ; disable timeout + + push eax + mov cx,cb_KeyEvent + call get_dict_entry + pop ecx + jc gfx_input_90 + + cmp dl,t_code + stc + jnz gfx_input_90 + + push eax + xchg eax,ecx + mov word [pstack_ptr],1 + mov dl,t_int + xor cx,cx + call set_pstack_tos + mov word [rstack_ptr],1 + xor cx,cx + mov dl,t_code + stc + sbb eax,eax + call set_rstack_tos + pop eax + + call run_pscode + jnc gfx_input_50 + + call ps_status_info + call get_key + stc + jmp gfx_input_90 + +gfx_input_50: + mov cx,2 + call get_pstack_tos + jc gfx_input_90 + cmp dl,t_string + stc + jnz gfx_input_90 + + pop cx + pop di + push di + push cx + + or di,di + jz gfx_input_70 + or cx,cx + jz gfx_input_70 + + lin2segofs eax,fs,si + mov es,[boot_cs] +gfx_input_60: + fs lodsb + stosb + or al,al + loopnz gfx_input_60 + mov byte [es:di-1],0 + +gfx_input_70: + mov cx,1 + call get_pstack_tos + jc gfx_input_90 + cmp dl,t_int + stc + jnz gfx_input_90 + + xor cx,cx + push eax + call get_pstack_tos + pop ebx + jc gfx_input_90 + cmp dl,t_int + stc + jnz gfx_input_90 + + or eax,eax + jz gfx_input_20 + +gfx_input_90: + pop cx + pop di + + pop ds + pop es + pop fs + retf + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; es:si menu description +; +gfx_menu_init: + push fs + push es + push ds + + push cs + pop ds + + push es + pop fs + + cld + +gfx_menu_init_20: + push si + movzx eax,word [fs:si+menu_entries] + push ax + imul ax,ax,5 + add ax,2 + push eax + call calloc + mov [tmp_var_2],eax + pop eax + call calloc + mov [tmp_var_1],eax + pop cx + pop si + or eax,[tmp_var_2] + jz gfx_menu_init_90 + + push cx + + lin2segofs dword [tmp_var_1],es,bx + mov [es:bx],cx + add bx,2 + push dword [fs:si+menu_ent_list] + call so2lin + pop edi +gfx_menu_init_40: + mov byte [es:bx],t_string + mov [es:bx+1],edi + add bx,5 + movzx eax,word [fs:si+menu_ent_size] + add edi,eax + loop gfx_menu_init_40 + + pop cx + + lin2segofs dword [tmp_var_2],es,bx + mov [es:bx],cx + add bx,2 + push dword [fs:si+menu_arg_list] + call so2lin + pop edi +gfx_menu_init_50: + mov byte [es:bx],t_string + mov [es:bx+1],edi + add bx,5 + movzx eax,word [fs:si+menu_arg_size] + add edi,eax + loop gfx_menu_init_50 + + push dword [fs:si+menu_default] + call so2lin + pop dword [tmp_var_3] + + mov cx,cb_MenuInit + call get_dict_entry + jc gfx_menu_init_90 + + cmp dl,t_code + stc + jnz gfx_menu_init_90 + + push eax + + mov word [pstack_ptr],3 + + mov eax,[tmp_var_1] + mov dl,t_array + mov cx,2 + call set_pstack_tos + + mov eax,[tmp_var_2] + mov dl,t_array + mov cx,1 + call set_pstack_tos + + mov eax,[tmp_var_3] + mov dl,t_string + xor cx,cx + call set_pstack_tos + + mov word [rstack_ptr],1 + xor cx,cx + mov dl,t_code + stc + sbb eax,eax + call set_rstack_tos + + pop eax + + call run_pscode + jnc gfx_menu_init_90 + + call ps_status_info + call get_key + stc + +gfx_menu_init_90: + pop ds + pop es + pop fs + retf + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; [boot_cs]:si info text 1 +; [boot_cs]:di info text 2 (may be 0 --> no text 2) +; al 0/1 info/error +; +gfx_infobox_init: + push fs + push es + push ds + + push cs + pop ds + cld + + push ax + + mov cx,100h-1 + mov fs,[boot_cs] + + lin2segofs dword [infobox_buffer],es,bp + or si,si + jz gfx_infobox_init_40 +gfx_infobox_init_20: + fs lodsb + mov [es:bp],al + inc bp + or al,al + loopnz gfx_infobox_init_20 + or cx,cx + jz gfx_infobox_init_40 + mov si,di + or si,si + jz gfx_infobox_init_40 + inc cx + dec bp +gfx_infobox_init_25: + fs lodsb + mov [es:bp],al + inc bp + or al,al + loopnz gfx_infobox_init_25 +gfx_infobox_init_40: + mov byte [es:bp-1],0 + + mov cx,cb_InfoBoxInit + call get_dict_entry + + pop bx + + jc gfx_infobox_init_90 + + cmp dl,t_code + stc + jnz gfx_infobox_init_90 + + push eax + + mov word [pstack_ptr],2 + + movzx eax,bl + mov dl,t_int + xor cx,cx + call set_pstack_tos + + mov eax,[infobox_buffer] + mov dl,t_string + mov cx,1 + call set_pstack_tos + + mov word [rstack_ptr],1 + xor cx,cx + mov dl,t_code + stc + sbb eax,eax + call set_rstack_tos + + pop eax + call run_pscode + jnc gfx_infobox_init_90 + + call ps_status_info + call get_key + stc + +gfx_infobox_init_90: + pop ds + pop es + pop fs + retf + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +gfx_infobox_done: + push fs + push es + push ds + + push cs + pop ds + cld + + mov cx,cb_InfoBoxDone + call get_dict_entry + jc gfx_infobox_done_90 + + cmp dl,t_code + stc + jnz gfx_infobox_done_90 + + push eax + mov word [pstack_ptr],0 + mov word [rstack_ptr],1 + xor cx,cx + mov dl,t_code + stc + sbb eax,eax + call set_rstack_tos + + pop eax + call run_pscode + jnc gfx_infobox_done_90 + + call ps_status_info + call get_key + stc + +gfx_infobox_done_90: + pop ds + pop es + pop fs + retf + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; eax max +; [boot_cs]:si kernel name +; +gfx_progress_init: + push fs + push es + push ds + + push cs + pop ds + cld + + mov [progress_max],eax + and dword [progress_current],byte 0 + + mov cx,cb_ProgressInit + push si + call get_dict_entry + pop si + jc gfx_progress_init_90 + + cmp dl,t_code + stc + jnz gfx_progress_init_90 + + push eax + mov word [pstack_ptr],1 + + segofs2lin word [boot_cs],si,eax + mov dl,t_string + xor cx,cx + call set_pstack_tos + + mov word [rstack_ptr],1 + xor cx,cx + mov dl,t_code + stc + sbb eax,eax + call set_rstack_tos + + pop eax + call run_pscode + jnc gfx_progress_init_90 + + call ps_status_info + call get_key + stc + +gfx_progress_init_90: + pop ds + pop es + pop fs + retf + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +gfx_progress_done: + push fs + push es + push ds + + push cs + pop ds + cld + + mov cx,cb_ProgressDone + call get_dict_entry + jc gfx_progress_done_90 + + cmp dl,t_code + stc + jnz gfx_progress_done_90 + + push eax + mov word [pstack_ptr],0 + mov word [rstack_ptr],1 + xor cx,cx + mov dl,t_code + stc + sbb eax,eax + call set_rstack_tos + + pop eax + call run_pscode + jnc gfx_progress_done_90 + + call ps_status_info + call get_key + stc + +gfx_progress_done_90: + pop ds + pop es + pop fs + retf + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +gfx_progress_update: + push fs + push es + push ds + + push cs + pop ds + cld + + add [progress_current],eax + + mov cx,cb_ProgressUpdate + call get_dict_entry + jc gfx_progress_update_90 + + cmp dl,t_code + stc + jnz gfx_progress_update_90 + + push eax + mov word [pstack_ptr],2 + + mov eax,[progress_current] + mov dl,t_int + xor cx,cx + call set_pstack_tos + + mov eax,[progress_max] + mov dl,t_int + mov cx,1 + call set_pstack_tos + + mov word [rstack_ptr],1 + xor cx,cx + mov dl,t_code + stc + sbb eax,eax + call set_rstack_tos + + pop eax + call run_pscode + jnc gfx_progress_update_90 + + call ps_status_info + call get_key + stc + +gfx_progress_update_90: + pop ds + pop es + pop fs + retf + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +gfx_progress_limit: + push ds + + push cs + pop ds + mov [progress_max],eax + mov [progress_current],edx + + pop ds + retf + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; [boot_cs]:si password +; [boot_cs]:di image name +; +gfx_password_init: + push fs + push es + push ds + + push cs + pop ds + cld + + mov cx,cb_PasswordInit + push si + push di + call get_dict_entry + pop di + pop si + jc gfx_password_init_90 + + cmp dl,t_code + stc + jnz gfx_password_init_90 + + push eax + + mov word [pstack_ptr],2 + + segofs2lin word [boot_cs],si,eax + mov dl,t_string + xor cx,cx + push di + call set_pstack_tos + pop di + + segofs2lin word [boot_cs],di,eax + mov dl,t_string + mov cx,1 + call set_pstack_tos + + mov word [rstack_ptr],1 + xor cx,cx + mov dl,t_code + stc + sbb eax,eax + call set_rstack_tos + + pop eax + call run_pscode + jnc gfx_password_init_90 + +gfx_password_init_80: + call ps_status_info + call get_key + stc + +gfx_password_init_90: + pop ds + pop es + pop fs + retf + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; [boot_cs]:si password +; +gfx_password_done: + push fs + push es + push ds + + push cs + pop ds + cld + + mov cx,cb_PasswordDone + push si + call get_dict_entry + pop si + jc gfx_password_done_90 + + cmp dl,t_code + stc + jnz gfx_password_done_90 + + push eax + + mov word [pstack_ptr],1 + + segofs2lin word [boot_cs],si,eax + mov dl,t_string + xor cx,cx + call set_pstack_tos + + mov word [rstack_ptr],1 + xor cx,cx + mov dl,t_code + stc + sbb eax,eax + call set_rstack_tos + + pop eax + call run_pscode + jc gfx_password_done_80 + + xor cx,cx + call get_pstack_tos + jc gfx_password_done_90 + cmp dl,t_bool + stc + jnz gfx_password_done_90 + + cmp eax,byte 1 + jmp gfx_password_done_90 + +gfx_password_done_80: + call ps_status_info + call get_key + stc + +gfx_password_done_90: + pop ds + pop es + pop fs + retf + + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Internal functions. +; +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +timeout: + mov cx,cb_Timeout + call get_dict_entry + jc timeout_90 + + cmp dl,t_code + stc + jnz timeout_90 + + push eax + mov word [pstack_ptr],2 + + mov cx,1 + mov dl,t_int + mov eax,[input_timeout_start] + call set_pstack_tos + + xor cx,cx + mov dl,t_int + mov eax,[input_timeout] + call set_pstack_tos + + mov word [rstack_ptr],1 + xor cx,cx + mov dl,t_code + stc + sbb eax,eax + call set_rstack_tos + + pop eax + call run_pscode + jnc timeout_90 + + call ps_status_info + call get_key + stc + +timeout_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; eax time +; +timer: + mov cx,cb_Timer + push eax + call get_dict_entry + pop ebx + jc timer_90 + + cmp dl,t_code + stc + jnz timer_90 + + push eax + mov word [pstack_ptr],1 + + xor cx,cx + mov dl,t_int + xchg eax,ebx + call set_pstack_tos + + mov word [rstack_ptr],1 + xor cx,cx + mov dl,t_code + stc + sbb eax,eax + call set_rstack_tos + + pop eax + call run_pscode + jnc timer_90 + + call ps_status_info + call get_key + stc + +timer_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Initialize parameter & return stack. +; +; return: +; CY error +; +stack_init: + mov ax,param_stack_size + mov [pstack_size],ax + and word [pstack_ptr],byte 0 + mov eax,param_stack_size * 5 + call calloc + cmp eax,byte 1 + jc stack_init_90 + push eax + call lin2so + pop dword [pstack] + + mov ax,ret_stack_size + mov [rstack_size],ax + and word [rstack_ptr],byte 0 + mov eax,ret_stack_size * 5 + call calloc + cmp eax,byte 1 + jc stack_init_90 + push eax + call lin2so + pop dword [rstack] +stack_init_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Read a pstack entry. +; +; cx index +; +; return: +; eax value +; dl type +; cx index +; CF error +; +get_pstack_entry: + les bx,[pstack] + xor eax,eax + mov dl,al + cmp [pstack_size],cx + jb get_pstack_entry_90 + mov ax,5 + mul cx + add bx,ax + mov dl,[es:bx] + mov eax,[es:bx+1] +get_pstack_entry_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Write a pstack entry. +; +; cx index +; eax value +; dl type +; +; return: +; cx index +; CF error +; +set_pstack_entry: + les bx,[pstack] + cmp [pstack_size],cx + jb set_pstack_entry_90 + push eax + push dx + mov ax,5 + mul cx + add bx,ax + pop dx + mov [es:bx],dl + pop dword [es:bx+1] +set_pstack_entry_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Read pstack tos (no pop). +; +; cx index (rel. to tos, 0 = tos) +; +; return: +; eax value +; dl type +; cx index (absolute) +; CF error +; +get_pstack_tos: + mov ax,[pstack_ptr] + sub ax,1 + jc get_pstack_tos_90 + sub ax,cx + jc get_pstack_tos_90 + xchg ax,cx + call get_pstack_entry +get_pstack_tos_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Write pstack tos (no push). +; +; cx index (rel. to tos, 0 = tos) +; eax value +; dl type +; +; return: +; cx index (absolute) +; CF error +; +set_pstack_tos: + mov bx,[pstack_ptr] + sub bx,1 + jc set_pstack_tos_90 + sub bx,cx + jc set_pstack_tos_90 + xchg bx,cx + call set_pstack_entry +set_pstack_tos_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Rotate pstack up (cx-1'th element becomes tos). +; +; cx values to rotate (counted from tos) +; +; return: +; CF error +; +rot_pstack_up: + or cx,cx + jz rot_pstack_up_90 + les di,[pstack] + mov ax,[pstack_ptr] + sub ax,cx + jb rot_pstack_up_90 + cmp cx,byte 1 + jz rot_pstack_up_90 + add di,ax + shl ax,2 + add di,ax + dec cx + mov ax,cx + shl ax,2 + add cx,ax + mov ebx,[es:di] + mov dl,[es:di+4] + lea si,[di+5] + es rep movsb + mov [es:di],ebx + mov [es:di+4],dl + clc +rot_pstack_up_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Rotate pstack down (1st element becomes tos). +; +; cx values to rotate (counted from tos) +; +; return: +; CF error +; +rot_pstack_down: + or cx,cx + jz rot_pstack_down_90 + les di,[pstack] + mov ax,[pstack_ptr] + cmp ax,cx + jb rot_pstack_down_90 + cmp cx,byte 1 + jz rot_pstack_down_90 + add di,ax + shl ax,2 + add di,ax + dec di + lea si,[di-5] + dec cx + mov ax,cx + shl ax,2 + add cx,ax + mov ebx,[es:si+1] + mov dl,[es:si+5] + std + es rep movsb + cld + mov [es:si+1],ebx + mov [es:si+5],dl + clc +rot_pstack_down_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Read a rstack entry. +; +; cx index +; +; return: +; eax value +; dl type +; cx index +; CF error +; +get_rstack_entry: + les bx,[rstack] + xor eax,eax + mov dl,al + cmp [rstack_size],cx + jb get_rstack_entry_90 + mov ax,5 + mul cx + add bx,ax + mov dl,[es:bx] + mov eax,[es:bx+1] +get_rstack_entry_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Write a rstack entry. +; +; cx index +; eax value +; dl type +; +; return: +; cx index +; CF error +; +set_rstack_entry: + les bx,[rstack] + cmp [rstack_size],cx + jb set_rstack_entry_90 + push eax + push dx + mov ax,5 + mul cx + add bx,ax + pop dx + mov [es:bx],dl + pop dword [es:bx+1] +set_rstack_entry_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Read rstack tos (no pop). +; +; cx index (rel. to tos, 0 = tos) +; +; return: +; eax value +; dl type +; cx index (absolute) +; CF error +; +get_rstack_tos: + mov ax,[rstack_ptr] + sub ax,1 + jc get_rstack_tos_90 + sub ax,cx + jc get_rstack_tos_90 + xchg ax,cx + call get_rstack_entry +get_rstack_tos_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Write rstack tos (no push). +; +; cx index (rel. to tos, 0 = tos) +; eax value +; dl type +; +; return: +; cx index (absolute) +; CF error +; +set_rstack_tos: + mov bx,[rstack_ptr] + sub bx,1 + jc set_rstack_tos_90 + sub bx,cx + jc set_rstack_tos_90 + xchg bx,cx + call set_rstack_entry +set_rstack_tos_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Setup initial dictionary. +; +; return: +; CY error +; +dict_init: + push fs + mov eax,[mem] + lin2segofs eax,es,si + mov ecx,[es:si+fh_dict] + cmp ecx,byte 1 + jc dict_init_90 + add eax,ecx + lin2segofs eax,es,si + xor eax,eax + es lodsw + mov [dict_size],ax + ; the dictionary should fit in 64k + cmp ax,0fff0h/5 + cmc + jc dict_init_90 + + ; p_none is not part of the default dict + cmp ax,cb_functions + prim_functions - 1 + jb dict_init_90 + + imul eax,eax,5 + push es + push si + call calloc + pop si + pop es + cmp eax,byte 1 + jc dict_init_90 + + push eax + call lin2so + pop dword [dict] + + ; add default functions + + lfs bx,[dict] + add bx,cb_functions * 5 + xor cx,cx + inc cx +dict_init_20: + mov byte [fs:bx],t_prim + mov [fs:bx+1],cx + add bx,5 + inc cx + cmp cx,prim_functions + jb dict_init_20 + + ; add user defined things + + es lodsw + or ax,ax + jz dict_init_80 + cmp [dict_size],ax + jb dict_init_90 + lfs bx,[dict] + xchg ax,cx +dict_init_50: + es lodsw + cmp ax,[dict_size] + cmc + jc dict_init_90 + mov di,5 + mul di + xchg ax,di + es lodsb + mov [fs:bx+di],al + es lodsd + mov [fs:bx+di+1],eax + dec cx + jnz dict_init_50 + +dict_init_80: + clc +dict_init_90: + pop fs + ret + +%if debug + +dump_dict: + mov si,dmsg_09 + call printf + + xor cx,cx +dump_dict_20: + call get_dict_entry + jc dump_dict_90 + pf_arg_ushort 0,cx + pf_arg_uchar 1,dl + pf_arg_uint 2,eax + mov si,dmsg_10 + pusha + call printf + popa + + inc cx + cmp cx,[dict_size] + jb dump_dict_20 +dump_dict_90: + ret + +%endif + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Read a dictionary entry. +; +; cx index +; +; return: +; eax value +; dl type +; cx index +; CF error +; +get_dict_entry: + les bx,[dict] + xor eax,eax + mov dl,al + cmp [dict_size],cx + jb get_dict_entry_90 + mov ax,5 + mul cx + add bx,ax + mov dl,[es:bx] + mov eax,[es:bx+1] +get_dict_entry_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Write a dictionary entry. +; +; cx index +; eax value +; dl type +; +; return: +; cx index +; CF error +; +set_dict_entry: + les bx,[dict] + cmp [dict_size],cx + jb set_dict_entry_90 + push eax + push dx + mov ax,5 + mul cx + add bx,ax + pop dx + mov [es:bx],dl + pop dword [es:bx+1] +set_dict_entry_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Get some memory. +; +; eax memory size +; +; return: +; eax linear address (0 if the request failed) +; memory is initialized with 0 +; +calloc: + push eax + call malloc + pop ecx + or eax,eax + jz calloc_90 + push eax + lin2segofs eax,es,di + xor eax,eax + add ecx,byte 3 + shr ecx,2 + rep stosd + pop eax +calloc_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Get some memory. +; +; eax memory size +; +; return: +; eax linear address (0 if the request failed) +; +malloc: + xor ebp,ebp + ; only in 4-byte chunks + add eax,3 + and eax,~3 + jz malloc_90 + add eax,4 + mov ebx,[mem_free] + +malloc_20: + lin2segofs ebx,es,si + mov ecx,[es:si] + test cl,1 + jnz malloc_60 + and cl,~3 + cmp ecx,eax + jb malloc_70 + ; mark as occupied + or byte [es:si],1 + lea ebp,[ebx+4] + mov edi,ecx + sub edi,eax + cmp edi,byte 8 + jb malloc_90 + + add ebx,eax + or al,1 + mov [es:si],eax + lin2segofs ebx,es,si + mov [es:si],edi + + jmp malloc_90 +malloc_60: + and cl,~3 +malloc_70: + add ebx,ecx + cmp ebx,[mem_max] + jb malloc_20 +malloc_90: + xchg ebp,eax + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Free memory. +; +; eax linear address +; +free: + or eax,eax + jz free_90 + test al,3 + jnz free_90 + + ; extended memory + cmp eax,100000h + jae xfree + + sub eax,4 + + mov ebx,[mem_free] + mov ecx,ebx +free_10: + cmp eax,ebx + jnz free_70 + + lin2segofs ebx,es,si + test byte [es:si],1 + jz free_90 + + cmp ecx,ebx ; first block? + jz free_30 + + lin2segofs ecx,es,si + mov edx,[es:si] + test dl,1 + jnz free_30 ; prev block is used + + and dl,~3 ; prev block is free -> join them + push es + lin2segofs ebx,es,di + add edx,[es:di] + and dl,~3 + pop es + mov [es:si],edx + mov ebx,ecx + +free_30: + mov edx,ebx + lin2segofs ebx,es,si + and byte [es:si],~1 ; mark block as free + add edx,[es:si] + and dl,~3 + cmp edx,[mem_max] ; last block? + jae free_90 + + lin2segofs edx,es,si + mov edx,[es:si] + test dl,1 + jnz free_90 ; next block is used + + and dl,~3 ; next block is free -> join them + lin2segofs ebx,es,si + add [es:si],edx + jmp free_90 + +free_70: + mov ecx,ebx + lin2segofs ebx,es,si + add ebx,[es:si] + and bl,~3 + cmp ebx,[mem_max] + jb free_10 +free_90: + ret + + +%if debug +; dump memory chain +dump_malloc: + pushad + mov ebx,[mem_free] + +dump_malloc_30: + lin2segofs ebx,es,si + mov ecx,[es:si] + + pushad + mov ax,dmsg_07 + test cl,1 + jz dump_malloc_40 + mov ax,dmsg_08 +dump_malloc_40: + pf_arg_ushort 2,ax + and cl,~3 + sub ecx,4 + pf_arg_uint 0,ebx + pf_arg_uint 1,ecx + mov si,dmsg_03 + call printf + popad + + and ecx,byte ~3 + mov si,dmsg_05 + jz dump_malloc_80 + + add ebx,ecx + cmp ebx,[mem_max] + jz dump_malloc_90 + jb dump_malloc_30 + + pf_arg_uint 0,ebx + pf_arg_uint 1,edi + mov si,dmsg_04 +dump_malloc_80: + call printf +dump_malloc_90: + popad + ret +%endif + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; return: +; ebp total free memory +; edi largest free block +; +memsize: + xor ebp,ebp + xor edi,edi + mov ebx,[mem_free] +memsize_30: + lin2segofs ebx,es,si + mov ecx,[es:si] + + mov al,cl + and ecx,byte ~3 + jz memsize_90 + test al,1 + jnz memsize_50 + + lea eax,[ecx-4] + add ebp,eax + cmp eax,edi + jb memsize_50 + mov edi,eax +memsize_50: + add ebx,ecx + cmp ebx,[mem_max] + jb memsize_30 +memsize_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Get some memory (taken from extended memory). +; +; eax memory size +; +; return: +; eax linear address (0 if the request failed) +; +; !!! Currently a fake; it's just called _once_ anyway. !!! +xmalloc: + ; 2 - 3 MB, to avoid A20 handling + mov eax,200000h + + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Free memory (extended memory area). +; +; eax linear address +; +xfree: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Switch to protected mode. +; +; return: +; CF error (can't switch) +; +real_to_pm: + cli + pushad + + segofs2lin ds,word pm_gdt,dword [pm_gdt+2] + + mov eax,9b00000h + mov ax,cs + ; patch jmp instruction for later + mov [pm_to_real_20-2],ax + shl eax,4 + mov [pm_gdt_cs+2],eax + + mov eax,9300000h + mov ax,ss + shl eax,4 + mov [pm_gdt_ss+2],eax + + mov eax,9300000h + mov ax,ds + shl eax,4 + mov [pm_gdt_ds+2],eax + + mov eax,cr0 + test al,1 ; in prot mode (maybe vm86)? + stc + jnz real_to_pm_90 + or al,1 + + o32 lgdt [pm_gdt] + + mov cr0,eax + + jmp pm_cs:real_to_pm_20 +real_to_pm_20: + + mov ax,pm_ss + mov ss,ax + + mov ax,pm_ds + mov ds,ax + + mov ax,pm_es + mov es,ax + mov fs,ax + mov gs,ax + + clc +real_to_pm_90: + popad + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Switch to real mode. +; +pm_to_real: + pushad + + mov eax,cr0 + and al,~1 + mov cr0,eax + + jmp 0:pm_to_real_20 +pm_to_real_20: + + mov ax,cs + mov ds,ax + mov es,ax + mov fs,ax + mov gs,ax + + mov eax,[pm_gdt_ss+2] + shr eax,4 + mov ss,ax + + popad + sti + ret + + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Find out size of memory block. +; +; eax lin. address +; +; return: +; eax size +; +find_mem_size: + mov edx,[pscode_start] + cmp eax,edx + jb find_mem_size_10 + add edx,[pscode_size] + cmp eax,edx + jae find_mem_size_10 + + ; string constant + + lin2segofs eax,es,di + mov cx,0ffffh + sub cx,di + movzx edx,cx + mov al,0 + repnz scasb + xor eax,eax + jnz find_mem_size_90 + sub dx,cx + mov eax,edx + jmp find_mem_size_90 + +find_mem_size_10: + cmp eax,[mem_free] + jb find_mem_size_40 + cmp eax,[mem_max] + jae find_mem_size_40 + + ; malloc area + + mov ebx,[mem_free] + +find_mem_size_20: + lin2segofs ebx,es,si + mov ecx,[es:si] + and ecx,~3 + lea edx,[ebx+ecx] + + cmp eax,edx + jae find_mem_size_30 + + test byte [es:si],1 + jz find_mem_size_80 + + sub eax,ebx + cmp eax,4 + jb find_mem_size_80 ; within header + + sub ecx,eax + xchg eax,ecx + jmp find_mem_size_90 + +find_mem_size_30: + mov ebx,edx + cmp ebx,[mem_max] + jb find_mem_size_20 + jmp find_mem_size_80 + +find_mem_size_40: + mov ebp,[mem_archive] + or ebp,ebp + jz find_mem_size_70 + cmp eax,ebp + jb find_mem_size_70 + cmp eax,[mem_free] + jae find_mem_size_70 + + ; cpio archive area + +find_mem_size_50: + mov ecx,[mem_free] + sub ecx,26 + cmp ebp,ecx + jae find_mem_size_80 + + lin2segofs ebp,es,bx + cmp word [es:bx],71c7h + jnz find_mem_size_80 + + movzx ecx,word [es:bx+20] ; file name size + inc cx + and cx,~1 ; align + + lea ecx,[ecx+ebp+26] ; data start + + cmp eax,ecx + jb find_mem_size_80 ; within header area + + mov edx,[es:bx+22] ; data size + rol edx,16 ; strange word order + + mov ebp,edx + inc ebp + and ebp,byte ~1 ; align + add ebp,ecx ; next record + + add ecx,edx + + cmp eax,ebp + jae find_mem_size_50 + + sub ecx,eax + jb find_mem_size_80 ; within alignment area + + xchg eax,ecx + jmp find_mem_size_90 + +find_mem_size_70: + + ; some other area + +find_mem_size_80: + xor eax,eax + +find_mem_size_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Find file. +; +; eax file name (lin) +; +; return: +; eax file start (lin) +; +; Note: use find_mem_size to find out the file size +; +find_file: + lin2segofs eax,fs,si + mov ebp,[mem_archive] + or ebp,ebp + jz find_file_80 +find_file_20: + lin2segofs ebp,es,bx + cmp word [es:bx],71c7h + jnz find_file_80 + mov cx,[es:bx+20] ; file name size (incl. final 0) + movzx edx,cx + inc dx + and dx,~1 ; align + lea ebp,[ebp+edx+26] ; points to data start + lea di,[bx+26] + or cx,cx + jz find_file_50 + push si + fs rep cmpsb + pop si + jnz find_file_50 + xchg eax,ebp + jmp find_file_90 +find_file_50: + mov ecx,[es:bx+22] ; data size + rol ecx,16 ; strange word order + inc ecx + and ecx,byte ~1 ; align + add ebp,ecx + mov ecx,ebp + add ecx,26 + cmp ecx,[mem_free] + jb find_file_20 +find_file_80: + xor eax,eax +find_file_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Set graphics mode. +; +; [gfx_mode] graphics mode (either vbe or normal mode number) +; [vbe_buffer] buffer for vbe info +; +; return: +; CF error +; +set_mode: + push es + mov ax,[gfx_mode] + test ah,ah + jnz set_mode_20 + int 10h + mov word [window_seg_w],0a000h + and word [window_seg_r],byte 0 + mov byte [mapped_window],0 + + mov al,[gfx_mode] + cmp al,13h + jnz set_mode_102 + ; 320x200, 8 bit + mov word [screen_width],320 + mov word [screen_height],200 + mov word [screen_line_len],320 + mov byte [pixel_bits],8 + mov byte [pixel_bytes],1 + call mode_init +set_mode_102: + jmp set_mode_90 +set_mode_20: + les di,[vbe_buffer] + mov ax,4f00h + and dword [es:di],byte 0 + push di ; you never know... + int 10h + pop di + cmp ax,4fh + jnz set_mode_80 + mov ax,4f01h + mov cx,[gfx_mode] + push di + int 10h + pop di + cmp ax,4fh + jnz set_mode_80 + + push word [es:di+10h] + pop word [screen_line_len] + + push word [es:di+12h] + pop word [screen_width] + push word [es:di+14h] + pop word [screen_height] + + mov al,[es:di+1bh] ; color mode (aka memory model) + mov ah,[es:di+19h] ; color depth + mov dh,ah + cmp al,6 ; direct color + jnz set_mode_30 + sub dh,[es:di+25h] ; reserved color bits + jmp set_mode_40 +set_mode_30: + cmp al,4 ; PL 8 + mov ah,8 + mov dh,ah + jz set_mode_40 + mov ah,0 +set_mode_40: + cmp ah,8 + jz set_mode_45 + cmp ah,16 + jz set_mode_45 + cmp ah,32 + jnz set_mode_80 +set_mode_45: + + mov [pixel_bits],ah + shr ah,3 + mov [pixel_bytes],ah + mov [color_bits],dh + + call mode_init + + ; we check if win A is readable _and_ writable; if not, we want + ; at least a writable win A and a readable win B + ; other, even more silly variations are not supported + + mov ax,[es:di+8] ; win seg A + mov bx,[es:di+10] ; win seg B + + or ax,ax + jz set_mode_80 + mov [window_seg_w],ax + and word [window_seg_r],byte 0 + mov dx,[es:di+2] ; win A/B attributes + and dx,707h + cmp dl,7 + jz set_mode_50 ; win A is rw + + or bx,bx + jz set_mode_80 + mov [window_seg_r],bx + mov cx,dx + and dx,305h + cmp dx,305h + jz set_mode_50 ; win A is w, win B is r + + and cx,503h + cmp cx,503h + jnz set_mode_80 + ; win A is r, win B is w + mov [window_seg_r],ax + mov [window_seg_w],bx +set_mode_50: + mov ax,[es:di+6] ; win size (in kb) + cmp ax,64 + jb set_mode_80 ; at least 64k + xor dx,dx + mov bx,[es:di+4] ; granularity (in kb) + or bx,bx + jz set_mode_80 + div bx + or dx,dx + jnz set_mode_80 + or ax,ax + jz set_mode_80 + mov [window_inc],al + mov byte [mapped_window],0ffh + mov ax,4f02h + mov bx,[gfx_mode] + int 10h + cmp ax,4fh + jnz set_mode_80 + mov al,0 + call set_win + jmp set_mode_90 +set_mode_80: + and word [gfx_mode],byte 0 + stc +set_mode_90 + pop es + ret + + +mode_init: + mov word [setpixel],setpixel_8 + mov word [setpixel_a],setpixel_a_8 + mov word [setpixel_t],setpixel_8 + mov word [setpixel_ta],setpixel_a_8 + mov word [getpixel],getpixel_8 + cmp byte [pixel_bits],8 + jz mode_init_90 + cmp byte [pixel_bits],16 + jnz mode_init_10 + mov word [setpixel],setpixel_16 + mov word [setpixel_a],setpixel_a_16 + mov word [setpixel_t],setpixel_t_16 + mov word [setpixel_ta],setpixel_ta_16 + mov word [getpixel],getpixel_16 + jmp mode_init_90 +mode_init_10: + cmp byte [pixel_bits],32 + jnz mode_init_90 + mov word [setpixel],setpixel_32 + mov word [setpixel_a],setpixel_a_32 + mov word [setpixel_t],setpixel_t_32 + mov word [setpixel_ta],setpixel_ta_32 + mov word [getpixel],getpixel_32 +mode_init_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Find graphics mode. +; +; edx width +; ecx height +; eax color bits +; [vbe_buffer] buffer for vbe info +; +; return: +; eax mode number +; CF 1 = not found +; +find_mode: + push es + + mov [tmp_write_data],dx + mov [tmp_write_data+2],cx + mov [tmp_write_data+4],ax + + lfs si,[vbe_mode_list] + cmp word [fs:si],0 + jnz find_mode_40 + + ; ok, get list first + + les di,[vbe_buffer] + mov ax,4f00h + and dword [es:di],byte 0 + push di + int 10h + pop di + cmp ax,4fh + jnz find_mode_30 + lfs si,[es:di+0eh] + les di,[vbe_mode_list] + mov cx,0ffh +find_mode_10: + fs lodsw + stosw + cmp ax,0ffffh + jz find_mode_20 + dec cx + jnz find_mode_10 + mov word [es:di],0ffffh +find_mode_20: + lfs si,[vbe_mode_list] + cmp word [fs:si],0 + jnz find_mode_40 + ; make sure it's not 0; mode 1 is the same as mode 0 + mov byte [fs:si],1 + jmp find_mode_40 +find_mode_30: + lfs si,[vbe_mode_list] + mov word [fs:si],0ffffh +find_mode_40: + fs lodsw + cmp ax,0ffffh + jz find_mode_80 + xchg ax,cx + les di,[vbe_buffer] + mov ax,4f01h + push fs + push si + push di + push cx + int 10h + pop cx + pop di + pop si + pop fs + cmp ax,4fh + jnz find_mode_40 + + test byte [es:di],1 ; mode supported? + jz find_mode_40 + + mov eax,[es:di+12h] ; size + cmp eax,[tmp_write_data] + jnz find_mode_40 + + mov dl,[es:di+1bh] ; color mode (aka memory model) + mov dh,[es:di+19h] ; color depth + + cmp dl,6 ; direct color + jnz find_mode_60 + cmp dh,32 + jz find_mode_70 + sub dh,[es:di+25h] ; reserved color bits + jmp find_mode_70 +find_mode_60: + cmp dl,4 ; PL8 + jnz find_mode_40 + mov dh,8 +find_mode_70: + cmp dh,[tmp_write_data+4] + jnz find_mode_40 + + movzx eax,cx + jmp find_mode_90 + +find_mode_80: + stc +find_mode_90: + pop es + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Activate an image from file. +; +; eax: lin ptr to image +; +; return: +; CY: error +; +image_init: + push eax + lin2segofs eax,es,bx + cmp dword [es:bx],0801050ah + jnz image_init_90 + + mov cx,[es:bx+8] + inc cx + jz image_init_80 + mov dx,[es:bx+10] + inc dx + jz image_init_80 + + push eax + push cx + push dx + push bx + push es + call find_mem_size + pop es + pop bx + pop dx + pop cx + pop edi + + cmp eax,381h + jb image_init_80 + + lea esi,[eax+edi-301h] + lin2segofs esi,fs,si + + cmp byte [fs:si],12 + jnz image_init_80 + + mov byte [image_type],1 ; pcx + + mov [image],edi + mov [image_width],cx + mov [image_height],dx + + lea ax,[bx+80h] + mov [image_data],ax + mov [image_data+2],es + + inc si + mov [image_pal],si + mov [image_pal+2],fs + + call parse_img + + lfs si,[image_pal] + les di,[gfx_pal] + + mov cx,300h + push cx + fs rep movsb + pop cx + + xor ax,ax + mov dx,cx + dec di + std + repz scasb + cld + setnz al + sub dx,cx + sub dx,ax + xchg ax,dx + xor dx,dx + mov cx,3 + div cx + sub ax,100h + neg ax + mov [pals],ax + + clc + jmp image_init_90 + +image_init_80: + stc +image_init_90: + pop eax + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Convert 32bit linear address to seg:ofs. +; +; dword [esp + 2]: linear address +; +; return: +; dword [esp + 2]: seg:ofs +; +; Notes: +; - changes no regs +; +lin2so: + push eax + mov eax,[esp + 6] + shr eax,4 + mov [esp + 8],ax + and word [esp + 6],byte 0fh + pop eax + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Convert seg:ofs to 32bit linear address. +; +; dword [esp + 2]: seg:ofs +; +; return: +; dword [esp + 2]: linear address +; +; Notes: +; - changes no regs +; +so2lin: + push eax + movzx eax,word [esp + 8] + and word [esp + 8],byte 0 + shl eax,4 + add [esp + 6],eax + pop eax + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Write text to console. +; +; si text (ACSIIZ) +; +printf: + mov byte [tmp_write_cnt],0 +printf_10: + call pf_next_char + or al,al + jz printf_90 + cmp al,'%' + jnz printf_70 + mov byte [tmp_write_pad],' ' + call pf_next_char + dec si + cmp al,'0' + jnz printf_20 + mov [tmp_write_pad],al +printf_20: + call get_number + mov [tmp_write_num],cx + call pf_next_char + or al,al + jz printf_90 + cmp al,'%' + jz printf_70 + + cmp al,'s' + jnz printf_30 + + push si + + call pf_next_arg + cmp byte [pf_gfx],0 + jz printf_25 + push es + lin2segofs eax,es,si + call write_str + pop es + jmp printf_27 +printf_25: + xchg ax,si + call write_str +printf_27: + sub cx,[tmp_write_num] + neg cx + mov al,' ' + call write_chars + pop si + jmp printf_10 + +printf_30: + cmp al,'u' + jnz printf_35 + + mov dx,10 +printf_31: + push si + call pf_next_arg + or dh,dh + jz printf_34 + test eax,eax + jns printf_34 + neg eax + push eax + mov al,'-' + call write_char + pop eax +printf_34: + mov cl,[tmp_write_num] + mov ch,[tmp_write_pad] + call number + cmp byte [pf_gfx],0 + jz printf_345 + push es + push ds + pop es + call write_str + pop es + jmp printf_347 +printf_345: + call write_str +printf_347: + pop si + jmp printf_10 + +printf_35: + cmp al,'x' + jnz printf_36 + +printf_35a: + mov dx,10h + jmp printf_31 + +printf_36: + cmp al,'d' + jnz printf_37 +printf_36a: + mov dx,10ah + jmp printf_31 + +printf_37: + cmp al,'i' + jz printf_36a + + cmp al,'p' + jnz printf_40 + mov al,'0' + call write_char + mov al,'x' + call write_char + jmp printf_35a + +printf_40: + cmp al,'c' + jnz printf_45 + + push si + call pf_next_arg + call write_char + pop si + jmp printf_10 +printf_45: + + ; more ... + + +printf_70: + call write_char + jmp printf_10 +printf_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; get next char for printf +; +; either from ds:si or es:si +; +pf_next_char: + xor eax,eax + cmp byte [pf_gfx],0 + jz pf_next_char_50 + es ; ok, this _is_ evil code... +pf_next_char_50: + lodsb + ret + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; return next printf arg +; +; return: +; eax arg +; +; changes no regs +; +pf_next_arg: + cmp byte [pf_gfx],0 + jz pf_next_arg_50 + push es + pushad + xor cx,cx + call get_pstack_tos + mov [tmp_write_data],eax + jnc pf_next_arg_20 + and dword [tmp_write_data],byte 0 + cmp word [pf_gfx_err],byte 0 + jnz pf_next_arg_20 + mov word [pf_gfx_err],pserr_pstack_underflow + jmp pf_next_arg_30 +pf_next_arg_20: + dec word [pstack_ptr] +pf_next_arg_30: + popad + pop es + mov eax,[tmp_write_data] + jmp pf_next_arg_90 +pf_next_arg_50: + push si + mov al,[tmp_write_cnt] + cbw + inc byte [tmp_write_cnt] + shl ax,2 + mov si,ax + mov eax,[si+tmp_write_data] + pop si +pf_next_arg_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; si text +; +; return: +; cx length +; +write_str: + xor cx,cx +write_str_10: + call pf_next_char + cmp byte [pf_gfx],0 + jz write_str_40 + call is_eot + jmp write_str_50 +write_str_40: + or al,al +write_str_50: + jz write_str_90 + call write_char + inc cx + jmp write_str_10 +write_str_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; al char +; cx count (must be > 0) +; +write_chars: + cmp cx,0 + jle write_chars_90 + call write_char + dec cx + jmp write_chars +write_chars_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; al char +; +write_char: + push es + pushad + cmp byte [pf_gfx],0 + jz write_char_50 + mov ebx,[pf_gfx_cnt] + inc ebx + cmp ebx,[pf_gfx_max] + jae write_char_90 ; leave room for final 0! + mov [pf_gfx_cnt],ebx + add ebx,[pf_gfx_buf] + dec ebx + lin2segofs ebx,es,di + mov ah,0 + mov [es:di],ax + jmp write_char_90 +write_char_50: + cmp al,0ah + jnz write_char_60 + push ax + mov al,0dh + mov bx,7 + mov ah,0eh + int 10h + pop ax +write_char_60: + mov bx,7 + mov ah,0eh + int 10h + +write_char_90: + popad + pop es + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Convert string to number. +; +; si string +; +; return: +; cx number +; si points past number +; CY not a number +; +get_number: + + xor cx,cx + mov ah,1 +get_number_10: + call pf_next_char + or al,al + jz get_number_90 + sub al,'0' + jb get_number_90 + cmp al,9 + ja get_number_90 + cbw + imul cx,cx,10 + add cx,ax + jmp get_number_10 +get_number_90: + dec si + shr ah,1 + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Convert a number to string. +; +; eax number +; cl field size +; ch padding char +; dl base +; +; return: +; si string +; +number: + push es + + push ds + pop es + mov di,num_buf + push ax + push cx + mov al,ch + mov cx,num_buf_end - num_buf + rep stosb + pop cx + pop ax + mov ch,0 + movzx ebx,dl +number_10: + xor edx,edx + div ebx + cmp dl,9 + jbe number_20 + add dl,27h +number_20: + add dl,'0' + dec di + mov [di],dl + or eax,eax + jz number_30 + cmp di,num_buf + ja number_10 +number_30: + mov si,di + or cx,cx + jz number_90 + cmp cl,num_buf_end - num_buf + jae number_90 + mov si,num_buf_end + sub si,cx +number_90: + pop es + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +ps_status_info: + xor dx,dx + call cons_xy + + mov si,msg_13 + call printf + + mov cx,4 +ps_status_info_10: + push cx + + call get_pstack_tos + jc ps_status_info_20 + pf_arg_ushort 0,cx + pf_arg_uchar 2,dl + pf_arg_uint 1,eax + mov si,msg_11 + jmp ps_status_info_30 +ps_status_info_20: + mov si,msg_12 +ps_status_info_30: + call printf + + pop cx + push cx + + call get_rstack_tos + jc ps_status_info_40 + pf_arg_ushort 0,cx + pf_arg_uchar 2,dl + pf_arg_uint 1,eax + mov si,msg_11 + jmp ps_status_info_50 +ps_status_info_40: + mov si,msg_12 +ps_status_info_50: + call printf + + mov si,msg_16 + call printf + + pop cx + dec cx + jge ps_status_info_10 + + mov si,msg_14 + call printf + + mov eax,[pscode_error_arg_0] + pf_arg_uint 1,eax + mov eax,[pscode_error_arg_1] + pf_arg_uint 2,eax + mov ax,[pscode_error] + pf_arg_ushort 0,ax + mov si,msg_17 + cmp ax,100h + jb ps_status_info_60 + mov si,msg_18 + cmp ax,200h + jb ps_status_info_60 + mov si,msg_19 +ps_status_info_60: + call printf + + mov eax,[pscode_instr] + pf_arg_uint 0,eax + mov eax,[pscode_arg] + pf_arg_uint 1,eax + mov eax,[pscode_error_arg_0] + pf_arg_uint 3,eax + mov eax,[pscode_error_arg_1] + pf_arg_uint 4,eax + mov al,[pscode_type] + pf_arg_uchar 2,al + + mov si,msg_10 + cmp al,t_sec + jnz ps_status_info_70 + mov si,msg_20 +ps_status_info_70: + call printf + + mov si,msg_15 + call printf + + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Read a key (blocking). +; +; return: +; eax key +; +get_key: + mov ah,10h + int 16h + and eax,0ffffh + push es + push word 0 + pop es + mov ecx,[es:417h-2] + xor cx,cx + add eax,ecx + pop es + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Read a key, return 0 if timed out +; +; return: +; eax key (or 0) +get_key_to: + call get_time + xchg eax,edx +get_key_to_20: + mov ah,11h + int 16h + jnz get_key_to_60 + cmp byte [run_idle],0 + jz get_key_to_25 + call idle +get_key_to_25: + push es + push byte 0 + pop es + mov ax,[es:417h] + pop es + cmp ax,[kbd_status] + mov [kbd_status],ax + jz get_key_to_30 + xor ax,ax + jmp get_key_to_60 + +get_key_to_30: + call get_time + cmp edx,eax + jz get_key_to_20 + + push eax + call timer + pop edx + + mov eax,[input_timeout] + or eax,eax + jz get_key_to_20 + + dec dword [input_timeout] + pushf + push edx + call timeout + pop edx + popf + jnz get_key_to_20 + + xor eax,eax + jmp get_key_to_90 + +get_key_to_60: + pushf + cmp dword [input_timeout],byte 0 + jz get_key_to_70 + and dword [input_timeout],byte 0 + call timeout +get_key_to_70: + popf + jnz get_key_to_80 + mov ax,[kbd_status] + shl eax,16 + mov ah,0ffh + jmp get_key_to_90 +get_key_to_80: + call get_key +get_key_to_90: + ret + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +clear_kbd_queue: + mov ah,11h + int 16h + jz clear_kbd_queue_90 + mov ah,10h + int 16h + jmp clear_kbd_queue +clear_kbd_queue_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +get_time: + push cx + push dx + xor ax,ax + int 1ah + push cx + push dx + pop eax + pop dx + pop cx + ret + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Set console cursor position. +; +; dh row +; dl column +; +; return: +; +cons_xy: + mov bh,0 + mov ah,2 + int 10h + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +idle_data dd 0 +idle_data2 dd 0 + +%include "kroete.inc" + +idle: + push es + push fs + push gs + pushad + + les si,[idle_data] + mov bx,[idle_data2] + call kroete + + popad + pop gs + pop fs + pop es + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Execute ps code. +; +; eax start address, relative to +; +; return: +; CF error +; +run_pscode: + mov [pscode_instr],eax + mov [pscode_next_instr],eax + mov dword [pscode_next_break],-1 + and word [pscode_error],byte 0 + mov dword [pscode_eval],-1 + + cmp [pscode_size],eax + mov bp,pserr_nocode + jb run_pscode_90 +run_pscode_10: + mov eax,[pscode_next_instr] + mov [pscode_instr],eax + cmp eax,-1 ; -1 is special: stop there + mov bp,pserr_ok + jz run_pscode_90 + mov ecx,-1 + xchg ecx,[pscode_eval] + cmp ecx,[pscode_eval] + jz run_pscode_15 + ; run opcode from exec instruction + mov ebx,eax + mov dl,t_sec + mov eax,ecx + jmp run_pscode_455 +run_pscode_15: + mov ebx,eax + add eax,[pscode_start] + lin2segofs eax,es,si + es lodsb + xor ecx,ecx + mov cl,al + and al,0fh + shr cl,4 + mov ah,cl + + and cl,7 + xor edx,edx + + cmp cl,0 + jz run_pscode_20 + + mov dl,[es:si] + cmp cl,1 + jz run_pscode_20 + + mov dx,[es:si] + cmp cl,2 + jz run_pscode_20 + + mov edx,[es:si] + and edx,0ffffffh + cmp cl,3 + jz run_pscode_20 + + mov edx,[es:si] +run_pscode_20: + stc + adc ebx,ecx ; ebx+ecx+1 + mov edi,ebx + add edi,[pscode_start] + + test ah,8 + jz run_pscode_30 + add ebx,edx +run_pscode_30: + cmp [pscode_size],ebx + mov bp,pserr_nocode + jb run_pscode_90 + + ; fix up signed integer + cmp al,t_int + jnz run_pscode_40 + cmp ah,0 + jz run_pscode_40 + cmp ah,4 + jae run_pscode_40 + shl ah,3 + mov cl,20h + sub cl,ah + shl edx,cl + sar edx,cl +run_pscode_40: + + cmp al,t_string + jnz run_pscode_45 + mov edx,edi +run_pscode_45: + xchg eax,edx + +run_pscode_455: + + ; dl: opcode + ; eax: instr arg + ; ebx: next instruction + + ; remember them + mov [pscode_type],dl + mov [pscode_arg],eax + mov [pscode_next_instr],ebx + + cmp dl,t_sec + jnz run_pscode_46 + + ; look it up in the dictionary, then continue + xchg ax,cx + call get_dict_entry + mov bp,pserr_invalid_dict + jc run_pscode_90 + + movzx edx,dl + mov [pscode_error_arg_0],eax + mov [pscode_error_arg_1],edx + +run_pscode_46: + pushad + cmp byte [show_debug_info],0 + jz run_pscode_47 + call ps_status_info +run_pscode_47: + mov eax,[pscode_next_break] + cmp eax,[pscode_instr] + jz run_pscode_475 + cmp byte [single_step],0 + jz run_pscode_48 +run_pscode_475: + mov byte [single_step],1 + call get_key + cmp ah,1 ; ESC + jnz run_pscode_477 + mov byte [single_step],0 + mov byte [show_debug_info],0 + jmp run_pscode_48 +run_pscode_477: + cmp ah,0fh ; Tab + jnz run_pscode_48 + mov byte [single_step],0 + mov eax,[pscode_next_instr] + mov [pscode_next_break],eax +run_pscode_48: + popad + + ; actually do something + cmp dl,t_none + jz run_pscode_50 + cmp dl,t_int + jz run_pscode_50 + cmp dl,t_unsigned + jz run_pscode_50 + cmp dl,t_bool + jz run_pscode_50 + cmp dl,t_string + jz run_pscode_50 + cmp dl,t_dict_idx + jz run_pscode_50 + cmp dl,t_ptr + jz run_pscode_50 + cmp dl,t_array + jnz run_pscode_52 +run_pscode_50: + ; t_none, t_int, t_bool, t_unsigned, t_string, t_code, t_dict_idx, t_array, t_ptr + + cmp dl,t_unsigned + jnz run_pscode_51 + mov dl,t_int ; always use t_int +run_pscode_51: + mov cx,[pstack_ptr] + cmp cx,[pstack_size] + mov bp,pserr_pstack_overflow + jae run_pscode_80 + inc word [pstack_ptr] + + xor cx,cx + call set_pstack_tos + jc run_pscode_90 + jmp run_pscode_10 + +run_pscode_52: + cmp dl,t_prim + jnz run_pscode_53 + + cmp eax,prim_functions + mov bp,pserr_invalid_prim + jae run_pscode_80 + xchg ax,si + add si,si + mov ax,[si+jt_p_none] + or ax,ax ; implemented? + jz run_pscode_80 + + call ax + jc run_pscode_90 + jmp run_pscode_10 + +run_pscode_53: + cmp dl,t_code + jnz run_pscode_54 + + ; branch + xchg eax,[pscode_next_instr] + + ; Check if we should just leave a mark on the + ; pstack or actually execute the code. + ; Maybe 2 different types (say: t_code, t_mark) would be better? + cmp byte [pscode_type],t_sec + jnz run_pscode_50 + + mov cx,[rstack_ptr] + cmp cx,[rstack_size] + mov bp,pserr_rstack_overflow + jae run_pscode_80 + inc word [rstack_ptr] + + xor cx,cx + call set_rstack_tos + jc run_pscode_90 + jmp run_pscode_10 + +run_pscode_54: + cmp dl,t_ret + jnz run_pscode_70 + + xor cx,cx + call get_rstack_tos + jnc run_pscode_55 + mov bp,pserr_rstack_underflow + jc run_pscode_90 +; ; treat this case as 'end' +; mov bp,pserr_ok +; clc +; jmp run_pscode_90 +run_pscode_55: + mov bp,pserr_invalid_rstack_entry + cmp dl,t_code + jz run_pscode_68 + cmp dl,t_if ; if + jz run_pscode_68 + cmp dl,t_loop ; loop + jz run_pscode_69 + cmp dl,t_repeat ; repeat + jz run_pscode_65 + cmp dl,t_for ; for + jz run_pscode_62 + cmp dl,t_forall ; forall + jnz run_pscode_80 + + ; forall + cmp word [rstack_ptr],byte 5 + mov bp,pserr_rstack_underflow + jc run_pscode_90 + + mov cx,1 + call get_rstack_tos ; count + cmp dl,t_int + jnz run_pscode_66 + + mov cx,2 + push eax + call get_rstack_tos ; length + pop esi + cmp dl,t_int + jnz run_pscode_66 + + mov cx,3 + push eax + push esi + call get_rstack_tos ; string/array + pop esi + pop ecx + cmp dl,t_array + jz run_pscode_57 + cmp dl,t_string + jz run_pscode_57 + cmp dl,t_ptr + jnz run_pscode_66 + +run_pscode_57: + ; dl,eax: string/array + ; esi: count + ; ecx: length + + inc esi + cmp esi,ecx + jae run_pscode_64 + + push dx + mov cx,1 + mov dl,t_int + push eax + push esi + mov eax,esi + call set_rstack_tos + pop eax + pop ecx + pop dx + + xchg dl,dh + call p_get + mov bp,pserr_invalid_range + jc run_pscode_80 + + mov cx,[pstack_ptr] + cmp cx,[pstack_size] + jae run_pscode_80 + inc word [pstack_ptr] + xor cx,cx + call set_pstack_tos + jc run_pscode_90 + + xor cx,cx + call get_rstack_tos + jmp run_pscode_69 + + +run_pscode_62: + ; for + cmp word [rstack_ptr],byte 5 + mov bp,pserr_rstack_underflow + jc run_pscode_90 + + mov cx,2 + call get_rstack_tos ; step + cmp dl,t_int + jnz run_pscode_66 + mov cx,1 + push eax + call get_rstack_tos ; limit + pop esi + cmp dl,t_int + jnz run_pscode_66 + push eax + mov cx,3 + push esi + call get_rstack_tos ; counter + pop esi + cmp dl,t_int + pop ecx + jnz run_pscode_66 + add eax,esi + or esi,esi + push eax + js run_pscode_63 + xchg eax,ecx +run_pscode_63: + cmp eax,ecx + pop eax + jl run_pscode_64 + + mov cx,3 + push eax + call set_rstack_tos + pop eax + mov cx,[pstack_ptr] + cmp cx,[pstack_size] + jae run_pscode_80 + inc word [pstack_ptr] + xor cx,cx + mov dl,t_int + call set_pstack_tos + jc run_pscode_90 + xor cx,cx + call get_rstack_tos + jmp run_pscode_69 +run_pscode_64: + mov cx,4 + call get_rstack_tos + sub word [rstack_ptr],byte 5 + jmp run_pscode_69 + + +run_pscode_65: + ; repeat + cmp word [rstack_ptr],byte 3 + mov bp,pserr_rstack_underflow + jc run_pscode_90 + push eax + mov cx,1 + call get_rstack_tos + pop ebx + cmp dl,t_int +run_pscode_66: + mov bp,pserr_invalid_rstack_entry + jnz run_pscode_80 + dec eax + jz run_pscode_67 + mov cx,1 + push ebx + call set_rstack_tos + pop eax + jmp run_pscode_69 +run_pscode_67: + mov cx,2 + call get_rstack_tos + sub word [rstack_ptr],byte 2 + +run_pscode_68: + dec word [rstack_ptr] +run_pscode_69: + mov [pscode_next_instr],eax + + jmp run_pscode_10 + +run_pscode_70: + +%if 0 +; Using undefined values has been legalized. +; See run_pscode_51 above... +; + cmp dl,t_none + mov bp,pserr_nop + jz run_pscode_80 +%endif + + cmp dl,t_sec + mov bp,pserr_invalid_dict_entry + jz run_pscode_80 + + cmp dl,t_end + mov bp,pserr_ok + jz run_pscode_90 + + ; illegal opcode + mov bp,pserr_invalid_opcode +run_pscode_80: + stc +run_pscode_90: + mov [pscode_error],bp + ret + + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; dl tos type +; return: +; eax tos +; dl actual tos types (even if CF is set) +; CF error +; +get_1arg: + xor eax,eax + cmp word [pstack_ptr],byte 1 + mov bp,pserr_pstack_underflow + jc get_1arg_90 + push dx + xor cx,cx + call get_pstack_tos + pop bx + ; ignore type check if t_none was requested + cmp bl,t_none + jz get_1arg_90 + cmp bl,dl + jz get_1arg_90 + mov bp,pserr_wrong_arg_types + stc +get_1arg_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; dl tos type +; dh tos + 1 type +; return: +; eax tos +; ecx tos + 1 +; dx actual tos types (even if CF is set) +; CF error +; +get_2args: + xor eax,eax + xor ecx,ecx + mov bx,dx + xor dx,dx + cmp word [pstack_ptr],byte 2 + mov bp,pserr_pstack_underflow + jc get_2args_90 + push bx + inc cx + call get_pstack_tos + push dx + push eax + xor cx,cx + call get_pstack_tos + pop ecx + pop bx + mov dh,bl + pop bx + + ; ignore type check if t_none was requested + cmp bh,t_none + jnz get_2args_50 + mov bh,dh +get_2args_50: + cmp bl,t_none + jnz get_2args_60 + mov bl,dl +get_2args_60: + cmp bx,dx + jz get_2args_90 + mov bp,pserr_wrong_arg_types +get_2args_80: + stc +get_2args_90: + ret + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Our primary functions. +; +prim_astart: + mov ax,[pstack_ptr] + inc ax + cmp [pstack_size],ax + mov bp,pserr_pstack_overflow + jb prim_astart_90 + mov [pstack_ptr],ax + mov dl,t_prim + mov eax,(jt_p_astart - jt_p_none) / 2 ; we need just some mark + xor cx,cx + call set_pstack_tos +prim_astart_90: + ret + + +prim_aend: + xor cx,cx +prim_aend_10: + push cx + call get_pstack_tos + pop cx + mov bp,pserr_pstack_underflow + jc prim_aend_90 + inc cx + cmp dl,t_prim + jnz prim_aend_10 + cmp eax,(jt_p_astart - jt_p_none) / 2 + jnz prim_aend_10 + + dec cx + push cx + mov ax,5 + mul cx + inc ax + inc ax + movzx eax,ax + call calloc + pop cx + or eax,eax + mov bp,pserr_no_memory + stc + jz prim_aend_90 + + push cx + push eax + + lin2segofs eax,es,di + mov [es:di],cx + inc di + inc di + +prim_aend_40: + sub cx,1 + jc prim_aend_60 + + push es + push di + push cx + call get_pstack_tos + pop cx + pop di + pop es + + mov [es:di],dl + mov [es:di+1],eax + add di,5 + jmp prim_aend_40 + +prim_aend_60: + + pop eax + pop cx + sub [pstack_ptr],cx + mov dl,t_array + xor cx,cx + call set_pstack_tos +prim_aend_90: + ret + + +prim_get: + mov dx,t_int + (t_array << 8) + call get_2args + jnc prim_get_10 + cmp dx,t_int + (t_string << 8) + jz prim_get_10 + cmp dx,t_int + (t_ptr << 8) + stc + jnz prim_get_90 +prim_get_10: + call p_get + jc prim_get_90 + + dec word [pstack_ptr] + xor cx,cx + call set_pstack_tos +prim_get_90: + ret + + +; dh, ecx obj +; eax index +; Return: +; dl, eax element +; CF 0/1 ok/not ok +; +p_get: + cmp dh,t_array + jz p_get_50 + cmp dh,t_string + jz p_get_10 + cmp dh,t_ptr + stc + jnz p_get_90 +p_get_10: + add ecx,eax + lin2segofs ecx,es,di + mov dl,t_int + movzx eax,byte [es:di] + jmp p_get_80 +p_get_50: + lin2segofs ecx,es,di + mov bp,pserr_invalid_range + cmp ax,[es:di] + cmc + jc p_get_90 + + add di,ax + add ax,ax + add ax,ax + add di,ax + + mov dl,[es:di+2] + mov eax,[es:di+3] +p_get_80: + clc +p_get_90: + ret + +prim_put: + mov bp,pserr_pstack_underflow + cmp word [pstack_ptr],byte 3 + jc prim_put_90 + + mov bp,pserr_wrong_arg_types + mov cx,2 + call get_pstack_tos + mov dh,0 + push dx + push eax + mov dx,t_none + (t_int << 8) + call get_2args + pop ebx + pop bp + shl edx,16 + mov dx,bp + rol edx,8 + cmp dx,t_int + (t_array << 8) + jz prim_put_50 + cmp edx,t_int + (t_string << 8) + (t_int << 24) + jz prim_put_30 + cmp edx,t_int + (t_ptr << 8) + (t_int << 24) + stc + mov bp,pserr_wrong_arg_types + jnz prim_put_90 +prim_put_30: + add ebx,ecx + lin2segofs ebx,es,di + mov [es:di],al + jmp prim_put_80 +prim_put_50: + shr edx,24 + lin2segofs ebx,es,di + + cmp cx,[es:di] + cmc + mov bp,pserr_invalid_range + jc prim_put_90 + + add di,cx + add cx,cx + add cx,cx + add di,cx + + mov [es:di+2],dl + mov [es:di+3],eax + +prim_put_80: + sub word [pstack_ptr],byte 3 +prim_put_90: + ret + + +prim_length: + mov dl,t_none + call get_1arg + jc prim_length_90 + call get_length + jc prim_length_90 + xor cx,cx + mov dl,t_int + call set_pstack_tos +prim_length_90: + ret + + +; dl, eax obj +; Return: +; eax length +; CF 0/1 ok/not ok +; +get_length: + cmp dl,t_ptr + jz get_length_10 + lin2segofs eax,es,si + cmp dl,t_array + jz get_length_20 + cmp dl,t_string + jz get_length_30 + stc + jmp get_length_90 +get_length_10: + call find_mem_size + jmp get_length_80 +get_length_20: + movzx eax,word [es:si] + jmp get_length_80 +get_length_30: + xor cx,cx + xor eax,eax +get_length_40: + es lodsb + call is_eot + loopnz get_length_40 ; max 64k length + not cx + movzx eax,cx +get_length_80: + clc +get_length_90: + ret + + +prim_array: + mov dl,t_int + call get_1arg + jc prim_array_90 + cmp eax,(0fff0h-2)/5 + cmc + mov bp,pserr_invalid_range + jc prim_array_90 + push ax + mov cx,5 + mul cx + inc ax + inc ax + call calloc + pop cx + or eax,eax + stc + mov bp,pserr_no_memory + jz prim_array_90 + + lin2segofs eax,es,di + mov [es:di],cx + + xor cx,cx + mov dl,t_array + call set_pstack_tos +prim_array_90: + ret + + +prim_pop: + cmp word [pstack_ptr],byte 1 + mov bp,pserr_pstack_underflow + jc prim_pop_90 + dec word [pstack_ptr] +prim_pop_90: + ret + +prim_dup: + mov cx,[pstack_ptr] + cmp cx,[pstack_size] + cmc + mov bp,pserr_pstack_overflow + jb prim_dup_90 + xor cx,cx + call get_pstack_tos + mov bp,pserr_pstack_underflow + jc prim_dup_90 + mov cx,0 + inc word [pstack_ptr] + call set_pstack_tos +prim_dup_90: + ret + + +prim_over: + mov cx,[pstack_ptr] + cmp cx,[pstack_size] + cmc + mov bp,pserr_pstack_overflow + jb prim_over_90 + mov cx,1 + call get_pstack_tos + mov bp,pserr_pstack_underflow + jc prim_over_90 + mov cx,0 + inc word [pstack_ptr] + call set_pstack_tos +prim_over_90: + ret + + +prim_index: + mov dl,t_int + call get_1arg + jc prim_index_90 + + movzx edx,word [pstack_ptr] + sub edx,2 + jc prim_index_90 + cmp edx,eax + mov bp,pserr_pstack_underflow + jc prim_index_90 + + inc ax + xchg ax,cx + call get_pstack_tos + xor cx,cx + call set_pstack_tos +prim_index_90: + ret + + +prim_exec: + mov dl,t_dict_idx + call pr_setobj_or_none + mov [pscode_eval],eax + ret + + +prim_add: + mov dx,t_int + (t_int << 8) + call get_2args + jnc prim_add_50 + cmp dx,t_int + (t_string << 8) + jz prim_add_50 + cmp dx,t_int + (t_ptr << 8) + stc + jnz prim_add_90 +prim_add_50: + add eax,ecx + dec word [pstack_ptr] + xor cx,cx + mov dl,dh + call set_pstack_tos +prim_add_90: + ret + + +prim_sub: + mov dx,t_int + (t_int << 8) + call get_2args + jnc prim_sub_50 + cmp dx,t_int + (t_string << 8) + jz prim_sub_50 + cmp dx,t_int + (t_ptr << 8) + stc + jnz prim_sub_90 +prim_sub_50: + xchg eax,ecx + sub eax,ecx + dec word [pstack_ptr] + xor cx,cx + mov dl,dh + call set_pstack_tos +prim_sub_90: + ret + +prim_mul: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_mul_90 + imul ecx + dec word [pstack_ptr] + xor cx,cx + mov dl,t_int + call set_pstack_tos +prim_mul_90: + ret + + +prim_div: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_div_90 + or eax,eax + stc + mov bp,pserr_div_by_zero + jz prim_div_90 + xchg eax,ecx + cdq + idiv ecx + dec word [pstack_ptr] + xor cx,cx + mov dl,t_int + call set_pstack_tos +prim_div_90: + ret + + +prim_mod: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_mod_90 + or eax,eax + stc + mov bp,pserr_div_by_zero + jz prim_div_90 + xchg eax,ecx + cdq + idiv ecx + xchg eax,edx + dec word [pstack_ptr] + xor cx,cx + mov dl,t_int + call set_pstack_tos +prim_mod_90: + ret + +prim_neg: + mov dl,t_int + call get_1arg + jc prim_neg_90 + neg eax + xor cx,cx + call set_pstack_tos +prim_neg_90: + ret + +prim_abs: + mov dl,t_int + call get_1arg + jc prim_abs_90 + or eax,eax + jns prim_abs_50 + neg eax +prim_abs_50: + xor cx,cx + call set_pstack_tos +prim_abs_90: + ret + +prim_min: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_min_90 + cmp eax,ecx + jle prim_min_50 + xchg eax,ecx +prim_min_50: + dec word [pstack_ptr] + xor cx,cx + call set_pstack_tos +prim_min_90: + ret + +prim_max: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_max_90 + cmp eax,ecx + jge prim_max_50 + xchg eax,ecx +prim_max_50: + dec word [pstack_ptr] + xor cx,cx + call set_pstack_tos +prim_max_90: + ret + +plog_args: + mov dx,t_int + (t_int << 8) + call get_2args + jnc plog_args_90 + cmp dx,t_int + (t_bool << 8) + jz plog_args_20 + cmp dx,t_bool + (t_int << 8) + jz plog_args_20 + cmp dx,t_bool + (t_bool << 8) + jz plog_args_20 + stc + pop ax + jmp plog_args_90 +plog_args_20: + mov dl,t_bool + or eax,eax + setnz al + movzx eax,al + or ecx,ecx + setnz cl + movzx ecx,cl +plog_args_90: + ret + + +prim_and: + call plog_args + and eax,ecx +prim_and_50: + dec word [pstack_ptr] + xor cx,cx + call set_pstack_tos + ret + +prim_or: + call plog_args + or eax,ecx + jmp prim_and_50 + +prim_xor: + call plog_args + xor eax,ecx + jmp prim_and_50 + +prim_not: + xor cx,cx + call get_pstack_tos + jc prim_not_90 + cmp dl,t_int + jz prim_not_50 + cmp dl,t_bool + mov bp,pserr_wrong_arg_types + stc + jnz prim_not_90 + xor al,1 + not eax +prim_not_50: + not eax + xor cx,cx + call set_pstack_tos +prim_not_90: + ret + + +prim_shl: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_shl_90 + xchg eax,ecx + shl eax,cl + cmp ecx,byte 20h + jb prim_shl_50 + xor eax,eax +prim_shl_50: + dec word [pstack_ptr] + xor cx,cx + call set_pstack_tos +prim_shl_90: + ret + + +prim_shr: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_shr_90 + xchg eax,ecx + cmp ecx,byte 20h + jb prim_shr_50 + mov cl,1fh +prim_shr_50: + sar eax,cl + dec word [pstack_ptr] + xor cx,cx + call set_pstack_tos +prim_shr_90: + ret + + +prim_def: + mov dx,t_none + (t_dict_idx << 8) + call get_2args + jc prim_def_90 + cmp dl,t_sec + mov bp,pserr_wrong_arg_types + stc + jz prim_def_90 + ; note: cx is index + call set_dict_entry + mov bp,pserr_invalid_dict + jc prim_def_90 + sub word [pstack_ptr],byte 2 +prim_def_90: + ret + + +prim_if: + mov dx,t_code + (t_bool << 8) + call get_2args + jnc prim_if_20 + cmp dh,t_int + jz prim_if_20 + cmp dh,t_none + jz prim_if_20 + mov cl,1 ; all pointer, strings, arrays are 'true' + cmp dh,t_ptr + jz prim_if_20 + cmp dh,t_string + jz prim_if_20 + cmp dh,t_array + jnz prim_if_80 +prim_if_20: + sub word [pstack_ptr],byte 2 + or ecx,ecx + jz prim_if_90 + + ; branch + xchg eax,[pscode_next_instr] + + mov cx,[rstack_ptr] + cmp cx,[rstack_size] + mov bp,pserr_rstack_overflow + jae prim_if_80 + inc word [rstack_ptr] + + xor cx,cx + mov dl,t_if ; mark as 'if' block + call set_rstack_tos + jnc prim_if_90 + +prim_if_80: + stc +prim_if_90: + ret + + +prim_ifelse: + mov cx,2 + call get_pstack_tos + jc prim_ifelse_90 + mov bp,pserr_wrong_arg_types + cmp dl,t_bool + jz prim_ifelse_10 + cmp dl,t_int + jz prim_ifelse_10 + cmp dl,t_none + jz prim_ifelse_10 + mov al,1 ; all pointer, strings, arrays are 'true' + cmp dl,t_ptr + jz prim_ifelse_10 + cmp dl,t_string + jz prim_ifelse_10 + cmp dl,t_array + jnz prim_ifelse_80 +prim_ifelse_10: + push eax + mov dx,t_code + (t_code << 8) + call get_2args + pop ebx + jc prim_ifelse_90 + + sub word [pstack_ptr],byte 3 + or ebx,ebx + jz prim_ifelse_20 + xchg dl,dh + xchg eax,ecx +prim_ifelse_20: + ; branch + xchg eax,[pscode_next_instr] + + mov cx,[rstack_ptr] + cmp cx,[rstack_size] + mov bp,pserr_rstack_overflow + jae prim_ifelse_80 + inc word [rstack_ptr] + + xor cx,cx + mov dl,t_if ; mark as 'if' block + call set_rstack_tos + jnc prim_ifelse_90 + +prim_ifelse_80: + stc +prim_ifelse_90: + ret + + + +; compare 2 strings +; return: +; cl, al last compared chars (if !=) +; edx length of identical parts +pcmp_str: + push fs + lin2segofs eax,fs,si + lin2segofs ecx,es,di + + xor ecx,ecx + xor eax,eax + xor edx,edx +pcmp_str_20: + mov ah,al + mov ch,cl + mov al,[fs:si] + mov cl,[es:di] + cmp al,cl + jnz pcmp_str_50 + or al,al + jz pcmp_str_50 + or cl,cl + jz pcmp_str_50 + inc si + jnz pcmp_str_30 + mov bx,fs + add bx,1000h + mov fs,bx +pcmp_str_30: + inc di + jnz pcmp_str_40 + mov bx,es + add bx,1000h + mov es,bx +pcmp_str_40: + inc edx + cmp edx,1 << 20 ; avoid infinite loop + jb pcmp_str_20 +pcmp_str_50: + pop fs + ret + + +pcmp_args: + ; integer + mov dx,t_int + (t_int << 8) + push bx + call get_2args + pop bx + jnc pcmp_args_90 + + ; strings + cmp dx,t_string + (t_string << 8) + jz pcmp_args_60 + + ; two identical objects + cmp dl,dh + jz pcmp_args_90 + + cmp bl,1 + jc pcmp_args_80 + + cmp eax,ecx + jnz pcmp_args_90 + mov al,dl + mov cl,dh + jmp pcmp_args_90 + +pcmp_args_60: + call pcmp_str + + jmp pcmp_args_90 +pcmp_args_80: + pop ax ; skip last return +pcmp_args_90: + ret + +pcmp_true: + mov dl,t_bool + mov eax,1 + dec word [pstack_ptr] + xor cx,cx + call set_pstack_tos + ret + +pcmp_false: + mov dl,t_bool + mov eax,0 + dec word [pstack_ptr] + xor cx,cx + call set_pstack_tos + ret + +prim_eq: + mov bl,1 + call pcmp_args + cmp ecx,eax + jz pcmp_true + jmp pcmp_false + +prim_ne: + mov bl,1 + call pcmp_args + cmp ecx,eax + jnz pcmp_true + jmp pcmp_false + +prim_gt: + mov bl,0 + call pcmp_args + cmp ecx,eax + jg pcmp_true + jmp pcmp_false + +prim_ge: + mov bl,0 + call pcmp_args + cmp ecx,eax + jge pcmp_true + jmp pcmp_false + +prim_lt: + mov bl,0 + call pcmp_args + cmp ecx,eax + jl pcmp_true + jmp pcmp_false + +prim_le: + mov bl,0 + call pcmp_args + cmp ecx,eax + jle pcmp_true + jmp pcmp_false + + +prim_exch: + mov cx,2 + call rot_pstack_up + mov bp,pserr_pstack_underflow + ret + + +prim_rot: + mov cx,3 + call rot_pstack_up + mov bp,pserr_pstack_underflow + ret + + +prim_roll: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_roll_90 + or ecx,ecx + jz prim_roll_90 + movzx edx,word [pstack_ptr] + sub edx,2 + cmp edx,ecx + mov bp,pserr_pstack_underflow + jc prim_roll_90 + cdq + idiv ecx + sub word [pstack_ptr],byte 2 + ; ecx is max. 14 bit + or dx,dx + jz prim_roll_90 + js prim_roll_50 +prim_roll_40: + push dx + push cx + call rot_pstack_down + pop cx + pop dx + dec dx + jnz prim_roll_40 + jmp prim_roll_90 +prim_roll_50: + neg dx +prim_roll_60: + push dx + push cx + call rot_pstack_up + pop cx + pop dx + dec dx + jnz prim_roll_60 + clc +prim_roll_90: + ret + +prim_dtrace: + mov byte [single_step],1 + mov byte [show_debug_info],1 + ret + +prim_trace: + mov byte [single_step],1 + mov byte [show_debug_info],0 + ret + +prim_return: + xor cx,cx +prim_return_10: + push cx + call get_rstack_tos + pop cx + mov bp,pserr_rstack_underflow + jc prim_return_90 + inc cx + cmp dl,t_code + jnz prim_return_10 ; skip if, loop, repeat, for, forall + + sub [rstack_ptr],cx + mov [pscode_next_instr],eax +prim_return_90: + ret + + +prim_exit: + xor cx,cx +prim_exit_10: + push cx + call get_rstack_tos + pop cx + mov bp,pserr_rstack_underflow + jc prim_exit_90 + inc cx + cmp dl,t_loop ; loop + jz prim_exit_60 + cmp dl,t_repeat ; repeat + jz prim_exit_40 + cmp dl,t_for ; for + jz prim_exit_30 + cmp dl,t_forall ; forall + jnz prim_exit_10 +prim_exit_30: + inc cx + inc cx +prim_exit_40: + inc cx +prim_exit_60: + push cx + call get_rstack_tos + pop cx + cmp dl,t_code + jz prim_exit_80 + cmp dl,t_exit + mov bp,pserr_invalid_rstack_entry + stc + jnz prim_exit_90 + +prim_exit_80: + inc cx + sub [rstack_ptr],cx + mov [pscode_next_instr],eax +prim_exit_90: + ret + +prim_loop: + xor cx,cx + call get_pstack_tos + cmp dl,t_code + mov bp,pserr_wrong_arg_types + stc + jnz prim_loop_90 + + dec word [pstack_ptr] + + ; branch + xchg eax,[pscode_next_instr] + + mov cx,[rstack_size] + sub cx,[rstack_ptr] + cmp cx,3 + mov bp,pserr_rstack_overflow + jb prim_loop_90 + add word [rstack_ptr],byte 2 + + mov dl,t_exit + mov cx,1 + call set_rstack_tos + xor cx,cx + mov dl,t_loop ; mark as 'loop' block + mov eax,[pscode_next_instr] + call set_rstack_tos +prim_loop_90: + ret + + +prim_repeat: + mov dx,t_code + (t_int << 8) + call get_2args + jc prim_repeat_90 + + sub word [pstack_ptr],byte 2 + + or ecx,ecx + jz prim_repeat_90 + + mov bp,pserr_invalid_range + stc + js prim_repeat_90 + + ; branch + xchg eax,[pscode_next_instr] + + mov dx,[rstack_size] + sub dx,[rstack_ptr] + cmp dx,4 + mov bp,pserr_rstack_overflow + jb prim_repeat_90 + add word [rstack_ptr],byte 3 + + push eax + xchg eax,ecx + mov dl,t_int + mov cx,1 + call set_rstack_tos + pop eax + mov cx,2 + mov dl,t_exit + call set_rstack_tos + xor cx,cx + mov dl,t_repeat ; mark as 'repeat' block + mov eax,[pscode_next_instr] + call set_rstack_tos +prim_repeat_90: + ret + + +prim_for: + mov bp,pserr_pstack_underflow + cmp word [pstack_ptr],byte 4 + jc prim_for_90 + mov cx,3 + call get_pstack_tos + cmp dl,t_int + stc + mov bp,pserr_wrong_arg_types + jnz prim_for_90 + mov cx,2 + push bp + push eax + call get_pstack_tos + pop edi + pop bp + cmp dl,t_int + stc + jnz prim_for_90 + + mov dx,t_code + (t_int << 8) + push eax + push edi + call get_2args + pop edi + pop esi + jc prim_for_90 + + ; don't remove start value! + sub word [pstack_ptr],byte 3 + + ; branch + xchg eax,[pscode_next_instr] + + mov dx,[rstack_size] + sub dx,[rstack_ptr] + cmp dx,6 + mov bp,pserr_rstack_overflow + jb prim_for_90 + add word [rstack_ptr],byte 5 + + push ecx + push esi + push edi + + mov dl,t_exit + mov cx,4 + call set_rstack_tos + + pop eax + mov dl,t_int + mov cx,3 + call set_rstack_tos + + pop eax + mov dl,t_int + mov cx,2 + call set_rstack_tos + + pop eax + mov dl,t_int + mov cx,1 + call set_rstack_tos + + xor cx,cx + mov dl,t_for ; mark as 'for' block + mov eax,[pscode_next_instr] + call set_rstack_tos +prim_for_90: + ret + + +prim_forall: + mov dx,t_code + (t_array << 8) + call get_2args + jnc prim_forall_30 + cmp dl,t_code + stc + jnz prim_forall_90 + cmp dh,t_string + jz prim_forall_30 + cmp dh,t_ptr + jz prim_forall_30 + cmp dh,t_none + stc + jnz prim_forall_90 + + ; nothing to do +prim_forall_20: + sub word [pstack_ptr],2 + clc + jmp prim_forall_90 + +prim_forall_30: + push eax ; code + push ecx ; string/array + xchg dl,dh + push dx + xchg eax,ecx + call get_length + pop dx + pop ecx + pop ebx + + mov bp,pserr_invalid_range + jc prim_forall_90 + + or eax,eax ; length == 0 + jz prim_forall_20 + + sub word [pstack_ptr],2 + + ; branch + xchg ebx,[pscode_next_instr] + + mov si,[rstack_size] + sub si,[rstack_ptr] + cmp si,6 + mov bp,pserr_rstack_overflow + jb prim_forall_90 + add word [rstack_ptr],5 + + push ecx + push dx + push eax + + mov dl,t_exit + xchg eax,ebx + mov cx,4 + call set_rstack_tos ; code + + pop eax + mov dl,t_int + mov cx,2 + call set_rstack_tos ; length + + pop dx + pop eax + push eax + push dx + mov cx,3 + call set_rstack_tos ; string/array + + xor eax,eax + mov dl,t_int + mov cx,1 + call set_rstack_tos ; count + + xor cx,cx + mov dl,t_forall ; mark as 'forall' block + mov eax,[pscode_next_instr] + call set_rstack_tos + + pop dx + pop ecx + xchg dl,dh + xor eax,eax + call p_get + mov bp,pserr_invalid_range + jc prim_forall_90 + + jmp pr_getobj + +prim_forall_90: + ret + + +prim_gettype: + mov dl,t_none + call get_1arg + jc prim_gettype_90 + movzx eax,dl + mov dl,t_int + xor cx,cx + call set_pstack_tos +prim_gettype_90: + ret + + +prim_settype: + mov dx,t_int + (t_none << 8) + call get_2args + jc prim_settype_90 + mov dl,al + and al,15 + xchg eax,ecx + dec word [pstack_ptr] + xor cx,cx + call set_pstack_tos +prim_settype_90: + ret + + +prim_screensize: + mov ax,[pstack_ptr] + inc ax + inc ax + cmp [pstack_size],ax + mov bp,pserr_pstack_overflow + jb prim_screensize_90 + mov [pstack_ptr],ax + mov dl,t_int + movzx eax,word [screen_width] + mov cx,1 + call set_pstack_tos + mov dl,t_int + movzx eax,word [screen_height] + xor cx,cx + call set_pstack_tos +prim_screensize_90: + ret + + +prim_imagesize: + mov ax,[pstack_ptr] + inc ax + inc ax + cmp [pstack_size],ax + mov bp,pserr_pstack_overflow + jb prim_imagesize_90 + mov [pstack_ptr],ax + mov dl,t_int + movzx eax,word [image_width] + mov cx,1 + call set_pstack_tos + mov dl,t_int + movzx eax,word [image_height] + xor cx,cx + call set_pstack_tos +prim_imagesize_90: + ret + + +prim_imagecolors: + movzx eax,word [pals] + jmp pr_getint + + +prim_setcolor: + call pr_setint + mov [gfx_color0],eax + call setcolor + ret + + +prim_currentcolor: + mov eax,[gfx_color0] + jmp pr_getint + + +prim_moveto: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_moveto_90 + sub word [pstack_ptr],byte 2 + mov [gfx_cur_x],cx + mov [gfx_cur_y],ax +prim_moveto_90: + ret + + +prim_rmoveto: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_rmoveto_90 + sub word [pstack_ptr],byte 2 + add [gfx_cur_x],cx + add [gfx_cur_y],ax + clc +prim_rmoveto_90: + ret + + +prim_currentpoint: + mov ax,[pstack_ptr] + inc ax + inc ax + cmp [pstack_size],ax + mov bp,pserr_pstack_overflow + jb prim_currentpoint_90 + mov [pstack_ptr],ax + mov dl,t_int + movzx eax,word [gfx_cur_x] + mov cx,1 + call set_pstack_tos + mov dl,t_int + movzx eax,word [gfx_cur_y] + xor cx,cx + call set_pstack_tos +prim_currentpoint_90: + ret + + +prim_lineto: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_lineto_90 + + mov [line_x1],ecx + mov [line_y1],eax + push cx + push ax + movsx eax,word [gfx_cur_x] + mov [line_x0],eax + movsx eax,word [gfx_cur_y] + mov [line_y0],eax + call line + pop word [gfx_cur_y] + pop word [gfx_cur_x] + + sub word [pstack_ptr],byte 2 +prim_lineto_90: + ret + + +prim_putpixel: + call goto_xy + call screen_segs + call [setpixel_t] + clc + ret + + +prim_getpixel: + call goto_xy + call screen_seg_r + mov si,di + xor eax,eax + call [getpixel] + jmp pr_getint + + +prim_setfont: + call pr_setptr_or_none + call font_init + ret + + +prim_currentfont: + push dword [font] + call so2lin + pop eax + jmp pr_getptr_or_none + + +prim_fontheight: + movzx eax,word [font_height] + jmp pr_getint + + +prim_setimage: + call pr_setptr_or_none + call image_init + ret + + +prim_currentimage: + mov eax,[image] + jmp pr_getptr_or_none + + +prim_settransparency: + call pr_setint + mov [transp],eax + ret + + +prim_currenttransparency: + mov eax,[transp] + jmp pr_getint + + +prim_show: + mov dl,t_string + call get_1arg + jc prim_show_90 + dec word [pstack_ptr] + lin2segofs eax,es,si + mov bx,[start_row] + or bx,bx + jz prim_show_50 + cmp bx,[cur_row2] + jae prim_show_90 + add bx,bx + mov si,[bx + row_start_ofs] + mov es,[row_start_seg] +prim_show_50: + call text_xy + clc +prim_show_90: + ret + + +prim_strsize: + mov dl,t_string + call get_1arg + jc prim_strsize_90 + dec word [pstack_ptr] + lin2segofs eax,es,si + call str_size + + mov ax,[pstack_ptr] + inc ax + inc ax + cmp [pstack_size],ax + mov bp,pserr_pstack_overflow + jb prim_strsize_90 + mov [pstack_ptr],ax + push dx + movzx eax,cx + mov dl,t_int + mov cx,1 + call set_pstack_tos + pop ax + mov dl,t_int + movzx eax,ax + xor cx,cx + call set_pstack_tos +prim_strsize_90: + ret + + +prim_image: + mov bp,pserr_pstack_underflow + cmp word [pstack_ptr],byte 4 + jc prim_image_90 + mov cx,3 + call get_pstack_tos + cmp dl,t_int + stc + mov bp,pserr_wrong_arg_types + jnz prim_image_90 + mov [line_x0],eax + mov cx,2 + push bp + call get_pstack_tos + pop bp + cmp dl,t_int + stc + jnz prim_image_90 + mov [line_y0],eax + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_image_90 + + sub word [pstack_ptr],byte 4 + + ; clip image width + ; note: image height is handled in draw_image + mov edx,[line_x0] + add edx,ecx + movzx ebx,word [image_width] + sub edx,ebx + jle prim_image_40 + sub ecx,edx +prim_image_40: + + cmp ecx,byte 0 + jle prim_image_90 + cmp eax,byte 0 + jz prim_image_90 + mov [line_x1],ecx + mov [line_y1],eax + push dword [gfx_cur] + call draw_image + pop dword [gfx_cur] + + clc +prim_image_90: + ret + + +prim_loadpalette: + mov cx,100h + xor dx,dx + call load_palette + clc + ret + +prim_tint: + mov bp,pserr_pstack_underflow + cmp word [pstack_ptr],byte 3 + jc prim_tint_90 + mov bp,pserr_wrong_arg_types + mov cx,2 + call get_pstack_tos + cmp dl,t_int + stc + jnz prim_tint_90 + push ax + mov dx,t_int + (t_int << 8) + call get_2args + pop dx + jc prim_tint_90 + + sub word [pstack_ptr],byte 3 + + xchg ax,bx + + push cx + push bx + call tint + pop dx + pop cx + + call load_palette + clc +prim_tint_90: + ret + + +prim_settintcolor: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_settintcolor_90 + + sub word [pstack_ptr],byte 2 + + mov [gfx_cs_tint_b],al + mov [gfx_cs_tint_g],ah + shr eax,16 + mov [gfx_cs_tint_r],al + mov [gfx_cs_b],cl + mov [gfx_cs_g],ch + shr ecx,16 + mov [gfx_cs_r],cl + + clc + +prim_settintcolor_90: + ret + + +prim_setpalette: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_setpalette_90 + + sub word [pstack_ptr],byte 2 + + cmp ecx,100h + jae prim_setpalette_90 + + push cx + les di,[gfx_pal] + add di,cx + add di,cx + add di,cx + mov [es:di+2],al + mov [es:di+1],ah + shr eax,16 + mov [es:di],al + pop dx + mov cx,1 + call load_palette + + clc + +prim_setpalette_90: + ret + + +prim_getpalette: + mov dl,t_int + call get_1arg + jc prim_getpalette_90 + + xchg eax,ecx + xor eax,eax + cmp ecx,100h + jae prim_getpalette_50 + + les di,[gfx_pal] + add di,cx + add di,cx + add di,cx + mov al,[es:di] + shl eax,16 + mov ah,[es:di+1] + mov al,[es:di+2] +prim_getpalette_50: + mov dl,t_int + xor cx,cx + call set_pstack_tos +prim_getpalette_90: + ret + + +prim_settransparentcolor: + call pr_setint + mov [transparent_color],ax + ret + + +prim_savescreen: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_savescreen_90 + push ax + push cx + mul ecx + mul dword [pixel_bytes] + pop dx + pop cx + mov bp,pserr_invalid_image_size + add eax,4 + jc prim_savescreen_90 + cmp eax,1 << 20 + cmc + jc prim_savescreen_90 + push cx + push dx + call malloc + pop dx + pop cx + or eax,eax + jz prim_savescreen_50 + lin2segofs eax,es,di + mov [es:di],dx + mov [es:di+2],cx + add di,4 + push eax + call save_bg + pop eax +prim_savescreen_50: + dec word [pstack_ptr] + xor cx,cx + mov dl,t_ptr + or eax,eax + jnz prim_savescreen_70 + mov dl,t_none +prim_savescreen_70: + call set_pstack_tos +prim_savescreen_90: + ret + + +prim_restorescreen: + mov dl,t_ptr + call get_1arg + jnc prim_restorescreen_20 + cmp dl,t_none + stc + jnz prim_restorescreen_90 + + jmp prim_restorescreen_80 + +prim_restorescreen_20: + cmp eax,100000h + jb prim_restorescreen_50 + + call real_to_pm + jc prim_restorescreen_80 + + mov dx,[es:eax] + mov cx,[es:eax+2] + + call pm_to_real + + mov bx,dx + imul bx,[pixel_bytes] + lea edi,[eax+4] + + call xrestore_bg + + jmp prim_restorescreen_80 +prim_restorescreen_50: + lin2segofs eax,es,di + mov dx,[es:di] + mov cx,[es:di+2] + add di,4 + mov bx,dx + imul bx,[pixel_bytes] + call restore_bg +prim_restorescreen_80: + dec word [pstack_ptr] + clc +prim_restorescreen_90: + ret + + +prim_malloc: + mov dl,t_int + call get_1arg + jc prim_malloc_90 + call calloc + or eax,eax + stc + mov bp,pserr_no_memory + jz prim_malloc_90 + xor cx,cx + mov dl,t_ptr + call set_pstack_tos +prim_malloc_90: + ret + + +prim_free: + mov dl,t_string + call get_1arg + jnc prim_free_10 + cmp dl,t_ptr + jz prim_free_10 + cmp dl,t_none + jz prim_free_50 + cmp dl,t_array + stc + jnz prim_free_90 +prim_free_10: + call free +prim_free_50: + dec word [pstack_ptr] + clc +prim_free_90: + ret + + +prim_memsize: + mov ax,[pstack_ptr] + inc ax + inc ax + cmp [pstack_size],ax + mov bp,pserr_pstack_overflow + jb prim_memsize_90 + mov [pstack_ptr],ax + call memsize + mov dl,t_int + xchg eax,ebp + push edi + mov cx,1 + call set_pstack_tos + pop eax + mov dl,t_int + xor cx,cx + call set_pstack_tos +prim_memsize_90: + ret + +prim_dumpmem: +%if debug + call dump_malloc +%endif + ret + + +prim_fillrect: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_fillrect_90 + mov dx,cx + mov cx,ax + mov eax,[gfx_color] + call fill_rect + sub word [pstack_ptr],byte 2 +prim_fillrect_90: + ret + + +prim_snprintf: + mov bp,pserr_pstack_underflow + cmp word [pstack_ptr],byte 3 + jc prim_snprintf_90 + mov bp,pserr_wrong_arg_types + mov cx,2 + call get_pstack_tos + cmp dl,t_string + stc + jnz prim_snprintf_90 + push eax + mov dx,t_string + (t_int << 8) + call get_2args + pop ebx + jc prim_snprintf_90 + + sub word [pstack_ptr],byte 3 + + mov [pf_gfx_buf],eax + mov [pf_gfx_max],ecx + and dword [pf_gfx_cnt],byte 0 + and word [pf_gfx_err],byte 0 + + or ecx,ecx + jz prim_snprintf_40 + ; clear buffer in case we have to print _nothing_ + lin2segofs eax,es,di + mov byte [es:di],0 +prim_snprintf_40: + + lin2segofs ebx,es,si + + mov byte [pf_gfx],1 + call printf + mov byte [pf_gfx],0 + + mov bp,[pf_gfx_err] + cmp bp,byte 0 +prim_snprintf_90: + ret + + +prim_editinit: + mov dx,t_string + (t_array << 8) + call get_2args + jc prim_editinit_90 + + lin2segofs ecx,es,si + push es + push si + push eax + call edit_get_params + pop eax + pop ecx + mov bp,pserr_invalid_data + jc prim_editinit_90 + + push dword [gfx_cur] + push ecx + lin2segofs eax,es,si + call edit_init + pop si + pop es + pop dword [gfx_cur] + + call edit_put_params + + sub word [pstack_ptr],byte 2 +prim_editinit_90: + ret + + +prim_editdone: + mov dx,t_array + call get_1arg + jc prim_editdone_90 + + lin2segofs eax,es,si + call edit_get_params + mov bp,pserr_invalid_data + jc prim_editdone_90 + + push word [edit_x] + pop word [gfx_cur_x] + push word [edit_y] + pop word [gfx_cur_y] + mov dx,[edit_width] + mov cx,[edit_height] + les di,[edit_bg] + add di,4 + mov bx,dx + imul bx,[pixel_bytes] + call restore_bg + + sub word [pstack_ptr],byte 1 +prim_editdone_90: + ret + + +prim_editshowcursor: + mov dx,t_array + call get_1arg + jc prim_editshowcursor_90 + + lin2segofs eax,es,si + call edit_get_params + mov bp,pserr_invalid_data + jc prim_editshowcursor_90 + + push dword [gfx_cur] + call edit_show_cursor + pop dword [gfx_cur] + + sub word [pstack_ptr],byte 1 +prim_editshowcursor_90: + ret + + +prim_edithidecursor: + mov dx,t_array + call get_1arg + jc prim_edithidecursor_90 + + lin2segofs eax,es,si + call edit_get_params + mov bp,pserr_invalid_data + jc prim_edithidecursor_90 + + push dword [gfx_cur] + call edit_hide_cursor + pop dword [gfx_cur] + + sub word [pstack_ptr],byte 1 +prim_edithidecursor_90: + ret + + +prim_editinput: + mov dx,t_int + (t_array << 8) + call get_2args + jc prim_editinput_90 + + lin2segofs ecx,es,si + push es + push si + push eax + call edit_get_params + pop eax + pop ecx + mov bp,pserr_invalid_data + jc prim_editinput_90 + + push dword [gfx_cur] + push ecx + push eax + call edit_hide_cursor + pop eax + call edit_input + call edit_show_cursor + pop si + pop es + pop dword [gfx_cur] + + call edit_put_params + + sub word [pstack_ptr],byte 2 +prim_editinput_90: + ret + + +prim_updatedisk: + call pr_setint + mov es,[boot_cs] + mov si,[boot_sysconfig] + mov [es:si+1],al + ret + + +prim_bootloader: + mov es,[boot_cs] + mov si,[boot_sysconfig] + movzx eax,byte [es:si] + jmp pr_getint + + +prim_bootdrive: + mov es,[boot_cs] + mov si,[boot_sysconfig] + movzx eax,byte [es:si+5] + jmp pr_getint + + +prim_reloadfs: + call pr_setint + mov es,[boot_cs] + mov si,[boot_sysconfig] + mov [es:si+6],al + ret + + +prim_usernote: + mov es,[boot_cs] + mov si,[boot_sysconfig] + movzx eax,byte [es:si+7] + jmp pr_getint + + +prim_getinfo: + mov dl,t_int + call get_1arg + jc prim_getinfo_90 + mov dl,t_int + mov es,[boot_cs] + mov si,[boot_sysconfig] + shl ax,2 + add si,ax + mov eax,[es:si+12] + xor cx,cx + call set_pstack_tos +prim_getinfo_90: + ret + + +prim_getbyte: + mov dl,t_ptr + call get_1arg + jc prim_getbyte_90 + lin2segofs eax,es,bx + movzx eax,byte [es:bx] + mov dl,t_int + xor cx,cx + call set_pstack_tos +prim_getbyte_90: + ret + + +prim_putbyte: + mov dx,t_int + (t_ptr << 8) + call get_2args + jc prim_putbyte_90 + lin2segofs ecx,es,bx + mov [es:bx],al + sub word [pstack_ptr],byte 2 +prim_putbyte_90: + ret + + +prim_getdword: + mov dl,t_ptr + call get_1arg + jc prim_getdword_90 + lin2segofs eax,es,bx + mov eax,[es:bx] + mov dl,t_int + xor cx,cx + call set_pstack_tos +prim_getdword_90: + ret + + +prim_putdword: + mov dx,t_int + (t_ptr << 8) + call get_2args + jc prim_putdword_90 + lin2segofs ecx,es,bx + mov [es:bx],eax + sub word [pstack_ptr],byte 2 +prim_putdword_90: + ret + + +prim_findfile: + mov dl,t_string + call get_1arg + jc prim_findfile_90 + call find_file + mov dl,t_ptr + or eax,eax + jnz prim_findfile_20 + mov dl,t_none +prim_findfile_20: + xor cx,cx + call set_pstack_tos +prim_findfile_90: + ret + + +prim_setmode: + mov dl,t_int + call get_1arg + jz prim_setmode_30 + cmp dl,t_none + stc + jnz prim_setmode_90 + xor eax,eax + mov cx,ax + jmp prim_setmode_80 +prim_setmode_30: + xchg [gfx_mode],ax + push ax + call set_mode + pop ax + jnc prim_setmode_60 + xchg [gfx_mode],ax + call set_mode + stc +prim_setmode_60: + sbb eax,eax + inc eax + + mov cx,[screen_width] + mov [clip_r],cx + + mov cx,[screen_height] + mov [clip_b],cx + + xor cx,cx + + mov [clip_l],cx + mov [clip_t],cx + +prim_setmode_80: + mov dl,t_bool + call set_pstack_tos +prim_setmode_90: + ret + + +prim_currentmode: + movzx eax,word [gfx_mode] + jmp pr_getint + + +prim_findmode: + mov bp,pserr_pstack_underflow + cmp word [pstack_ptr],byte 3 + jc prim_findmode_90 + + mov bp,pserr_wrong_arg_types + mov cx,2 + call get_pstack_tos + cmp dl,t_int + stc + jnz prim_findmode_90 + push eax + mov dx,t_int + (t_int << 8) + call get_2args + pop edx + jc prim_findmode_90 + + ; eax: color + ; ecx: height + ; edx: width + + call find_mode + jnc prim_findmode_50 + + mov dl,t_none + xor eax,eax + + jmp prim_findmode_60 + +prim_findmode_50: + mov dl,t_int + +prim_findmode_60: + sub word [pstack_ptr],byte 2 + + xor cx,cx + call set_pstack_tos + +prim_findmode_90: + ret + + +prim_colorbits: + movzx eax,byte [color_bits] + jmp pr_getint + + +prim_eject: + mov dl,t_int + call get_1arg + jc prim_eject_90 + mov dl,al + mov ax,4600h + int 13h + xor cx,cx + mov dl,t_int + movzx eax,ah + call set_pstack_tos +prim_eject_90: + ret + + +prim_poweroff: + mov ax,5300h + xor bx,bx + int 15h + jc prim_poweroff_90 + mov ax,5304h + xor bx,bx + int 15h + mov ax,5301h + xor bx,bx + int 15h + jc prim_poweroff_90 + mov ax,530eh + xor bx,bx + mov cx,102h + int 15h + jc prim_poweroff_90 + mov ax,5307h + mov cx,3 + mov bx,1 + int 15h +prim_poweroff_90: + clc + ret + + +prim_strstr: + mov dx,t_string + (t_string << 8) + call get_2args + jc prim_strstr_90 + + xor ebx,ebx + +prim_strstr_20: + push eax + push ecx + + push ebx + call pcmp_str + pop ebx + + jz prim_strstr_50 + + or al,al + jnz prim_strstr_30 + + or edx,edx + jnz prim_strstr_50 + +prim_strstr_30: + + or cl,cl + jz prim_strstr_40 + + pop ecx + pop eax + + inc ecx + inc ebx + jmp prim_strstr_20 + +prim_strstr_40 + xor ebx,ebx + jmp prim_strstr_60 +prim_strstr_50: + inc ebx +prim_strstr_60: + add esp,2*4 + xchg eax,ebx + dec word [pstack_ptr] + xor cx,cx + mov dl,t_int + call set_pstack_tos + +prim_strstr_90: + ret + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; sound primitives + +prim_soundgetvolume: + mov ax,[pstack_ptr] + inc ax + cmp [pstack_size],ax + mov bp,pserr_pstack_overflow + jb prim_sgv_90 + mov [pstack_ptr],ax + mov dl,t_int + movzx eax,byte [sound_vol] + xor cx,cx + call set_pstack_tos +prim_sgv_90: + ret + +prim_soundsetvolume: + mov dl,t_int + call get_1arg + jc prim_ssv_90 + dec word [pstack_ptr] + or eax,eax + jns prim_ssv_30 + xor eax,eax +prim_ssv_30: + cmp eax,100 + jl prim_ssv_50 + mov ax,100 +prim_ssv_50: + or eax,eax + jns prim_ssv_60 + xor ax,ax +prim_ssv_60: + mov [sound_vol],al + call mod_setvolume + clc +prim_ssv_90: + ret + +prim_soundgetsamplerate: + mov ax,[pstack_ptr] + inc ax + cmp [pstack_size],ax + mov bp,pserr_pstack_overflow + jb prim_sgsr_90 + mov [pstack_ptr],ax + mov dl,t_int + movzx eax,byte [sound_sample] + xor cx,cx + call set_pstack_tos +prim_sgsr_90: + ret + +prim_soundsetsamplerate: + mov dl,t_int + call get_1arg + jc prim_sssr_90 + dec word [pstack_ptr] + push eax + call sound_init + pop eax + call sound_setsample + clc +prim_sssr_90: + ret + + +prim_soundplay: + + + call sound_init + jc prim_splay_80 +prim_splay_80: + clc +prim_splay_90: + ret + + +prim_sounddone: + call sound_done + clc + ret + + +%if 0 +prim_soundtest: + mov dl,t_int + call get_1arg + jc prim_stest_90 + dec word [pstack_ptr] + + mov [sound_x],eax + call sound_test + clc +prim_stest_90: + ret +%endif + +prim_modload: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_modload_90 + sub word [pstack_ptr],byte 2 + xchg eax,ecx + + ; ecx file + ; eax player + + push dword [mem] + call lin2so + pop bx + pop es + cmp cl,[es:bx+fh_file_entries] + cmc + jc prim_modload_80 + + xor esi,esi + + imul dx,cx,sizeof_file_raw_t + add si,dx + + add si,sizeof_file_header_t + add esi,[mem] + + push esi + call lin2so + pop si + pop es + + mov ebx,[es:si+fi_raw_data] + add ebx,[mem] + + ; ebx: mod file + ; eax: player + + push eax + push ebx + call sound_init + pop ebx + pop eax + jc prim_modload_80 + + push ebx + call lin2so + pop di + pop es + + call mod_load + +prim_modload_80: + clc +prim_modload_90: + ret + + +prim_modplay: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_modplay_90 + sub word [pstack_ptr],byte 2 + xchg eax,ecx + + ; ecx start + ; eax player + + cmp byte [sound_ok],0 + jz prim_modplay_90 + + mov bx,cx + call mod_play + + clc +prim_modplay_90: + ret + + +prim_modplaysample: + mov bp,pserr_pstack_underflow + cmp word [pstack_ptr],byte 4 + jc prim_modps_90 + mov bp,pserr_wrong_arg_types + + mov cx,3 + call get_pstack_tos + cmp dl,t_int + stc + jnz prim_modps_90 + + mov cx,2 + push ax + call get_pstack_tos + pop bx + cmp dl,t_int + stc + jnz prim_modps_90 + + mov dx,t_int + (t_int << 8) + push bx + push ax + call get_2args + pop bx + pop dx + jc prim_modps_90 + + sub word [pstack_ptr],byte 4 + + xchg ax,dx + + ; 1: ax + ; 2: bx + ; 3: cx + ; 4: dx + + cmp byte [sound_ok],0 + jz prim_modps_90 + + call mod_playsample + + clc +prim_modps_90: + ret + + +%if 0 +prim_numtest: + mov dl,t_int + call get_1arg + jc prim_numtest_90 + + mov eax,[tmp_var_0 + 4*eax] + + mov dl,t_int + xor cx,cx + call set_pstack_tos + + clc +prim_numtest_90: + ret +%endif + + +prim_settextwrap: + call pr_setint + mov [line_wrap],ax + ret + + +prim_currenttextwrap: + movzx eax,word [line_wrap] + jmp pr_getint + + +prim_seteotchar: + call pr_setint + mov [char_eot],eax + ret + + +prim_currenteotchar: + mov eax,[char_eot] + jmp pr_getint + + +prim_setmaxrows: + call pr_setint + mov [max_rows],ax + ret + + +prim_currentmaxrows: + movzx eax,word [max_rows] + jmp pr_getint + + +prim_formattext: + mov dl,t_string + call get_1arg + jc prim_formattext_90 + dec word [pstack_ptr] + push eax + xor ax,ax + mov cx,max_text_rows + mov di,row_start_ofs + push ds + pop es + rep stosw + mov cx,link_entries * sizeof_link + mov di,link_list + rep stosb + pop eax + lin2segofs eax,es,si + or byte [txt_state],2 + call text_xy + and byte [txt_state],~2 + clc +prim_formattext_90: + ret + + +prim_gettextrows: + movzx eax,word [cur_row2] + jmp pr_getint + + +prim_setstartrow: + call pr_setint + mov [start_row],ax + ret + + +prim_getlinks: + movzx eax,word [cur_link] + jmp pr_getint + + +prim_settextcolors: + mov bp,pserr_pstack_underflow + cmp word [pstack_ptr],byte 4 + jc prim_settextcolors_90 + mov cx,3 + call get_pstack_tos + cmp dl,t_int + stc + mov bp,pserr_wrong_arg_types + jnz prim_settextcolors_90 + mov [gfx_color0],eax + mov [gfx_color],eax + mov cx,2 + push bp + call get_pstack_tos + pop bp + cmp dl,t_int + stc + jnz prim_settextcolors_90 + mov [gfx_color1],eax + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_settextcolors_90 + + sub word [pstack_ptr],byte 4 + + mov [gfx_color2],ecx + mov [gfx_color3],eax + + clc +prim_settextcolors_90: + ret + + +prim_currenttextcolors: + mov ax,[pstack_ptr] + add ax,4 + cmp [pstack_size],ax + mov bp,pserr_pstack_overflow + jb prim_currenttextcolors_90 + mov [pstack_ptr],ax + mov dl,t_int + mov eax,[gfx_color3] + xor cx,cx + call set_pstack_tos + mov dl,t_int + mov eax,[gfx_color2] + mov cx,1 + call set_pstack_tos + mov dl,t_int + mov eax,[gfx_color1] + mov cx,2 + call set_pstack_tos + mov dl,t_int + mov eax,[gfx_color0] + mov cx,3 + call set_pstack_tos +prim_currenttextcolors_90: + ret + + +prim_setlink: + call pr_setint + mov dx,[cur_link] + cmp ax,dx + jae prim_setlink_90 + mov [sel_link],ax +prim_setlink_90: + ret + + +prim_currentlink: + movzx eax,word [sel_link] + jmp pr_getint + + +; +; label, text, x, row +prim_getlink: + mov dl,t_int + call get_1arg + jc prim_getlink_90 + mov bp,pserr_invalid_range + cmp ax,[cur_link] + cmc + jc prim_getlink_90 + xchg ax,di + shl di,3 ; sizeof_link = 8 + add di,link_list + mov ax,[pstack_ptr] + add ax,3 + cmp [pstack_size],ax + mov bp,pserr_pstack_overflow + jb prim_getlink_90 + mov [pstack_ptr],ax + mov dl,t_string + segofs2lin ds, word label_buf,eax + mov cx,3 + call set_pstack_tos + mov dl,t_string + segofs2lin word [row_start_seg],word [di+li_text],eax + mov cx,2 + call set_pstack_tos + mov dl,t_int + movzx eax,word [di+li_x] + mov cx,1 + call set_pstack_tos + mov dl,t_int + movzx eax,word [di+li_row] + xor cx,cx + call set_pstack_tos + + mov es,[row_start_seg] + mov si,[di+li_label] + mov di,label_buf + mov cx,32 ; sizeof buf +prim_getlink_50: + es lodsb + cmp al,13h + jz prim_getlink_60 + or al,al + jz prim_getlink_60 + mov [di],al + inc di + loop prim_getlink_50 +prim_getlink_60: + mov byte [di],0 + clc +prim_getlink_90: + ret + + +prim_lineheight: + movzx eax,word [font_line_height] + jmp pr_getint + + +prim_currenttitle: + segofs2lin word [row_start_seg],word [page_title],eax + mov dl,t_string + jmp pr_getobj + + +prim_xsavescreen: + mov dx,t_int + (t_int << 8) + call get_2args + jc prim_xsavescreen_90 + push ax + push cx + mul ecx + pop dx + pop cx + mov bp,pserr_invalid_image_size + add eax,4 + jc prim_xsavescreen_90 + cmp eax,1 << 20 + cmc + jc prim_xsavescreen_90 + push cx + push dx + call xmalloc + pop dx + pop cx + or eax,eax + stc + mov bp,pserr_no_memory + jz prim_xsavescreen_90 + + call real_to_pm + jc prim_xsavescreen_50 + + mov [es:eax],dx + mov [es:eax+2],cx + + call pm_to_real + + push eax + lea edi,[eax+4] + call xsave_bg + pop eax + +prim_xsavescreen_50: + dec word [pstack_ptr] + xor cx,cx + mov dl,t_ptr + call set_pstack_tos +prim_xsavescreen_90: + ret + + +prim_videomodes: + mov ax,[pstack_ptr] + inc ax + cmp [pstack_size],ax + mov bp,pserr_pstack_overflow + jb prim_videomodes_90 + mov [pstack_ptr],ax + + mov es,[boot_cs] + mov si,[boot_sysconfig] + movzx cx,byte [es:si+4] + mov si,[es:si+2] + xor eax,eax + or cx,cx + jz prim_videomodes_40 +prim_videomodes_20: + cmp byte [es:si+fb_bits],0 + jz prim_videomodes_40 + add si,sizeof_fb_entry + inc eax + loop prim_videomodes_20 +prim_videomodes_40: + mov dl,t_int + xor cx,cx + call set_pstack_tos +prim_videomodes_90: + ret + + +; +; mode, width, height, ok +prim_getvideomode: + mov dl,t_int + call get_1arg + jc prim_getvm_90 + mov bp,pserr_invalid_range + mov fs,[boot_cs] + mov si,[boot_sysconfig] + movzx ecx,byte [fs:si+4] + cmp eax,ecx + cmc + jc prim_getvm_90 + imul di,ax,sizeof_fb_entry + add di,[fs:si+2] + + mov ax,[pstack_ptr] + add ax,3 + cmp [pstack_size],ax + mov bp,pserr_pstack_overflow + jb prim_getvm_90 + mov [pstack_ptr],ax + + mov dl,t_int + movzx eax,word [fs:di+fb_mode] + mov cx,3 + call set_pstack_tos + + mov dl,t_int + movzx eax,word [fs:di+fb_width] + mov cx,2 + call set_pstack_tos + + mov dl,t_int + movzx eax,word [fs:di+fb_height] + mov cx,1 + call set_pstack_tos + + mov dl,t_int + movzx eax,byte [fs:di+fb_ok] + xor cx,cx + call set_pstack_tos +prim_getvm_90: + ret + + +prim_usleep: + call pr_setint + + mov ecx,54944/2 + add eax,ecx + add ecx,ecx + xor edx,edx + div ecx + or eax,eax + jz prim_usleep_90 + mov ecx,eax + push ecx + call get_time + pop ecx + add ecx,eax +prim_usleep_20: + push ecx + call get_time + pop ecx + cmp eax,ecx + jbe prim_usleep_20 +prim_usleep_90: + ret + + +prim_time: + call get_time + jmp pr_getint + + +prim_setbrightness: + call pr_setint + mov [brightness],ax + ret + +prim_currentbrightness: + movzx eax,word [brightness] + jmp pr_getint + + +prim_fadein: + mov dx,t_int + (t_string << 8) + call get_2args + jc prim_get_90 + + sub word [pstack_ptr],byte 2 + + lin2segofs ecx,es,bx + call fade_in + + clc +prim_fadein_90: + ret + + +prim_fade: + mov bp,pserr_pstack_underflow + cmp word [pstack_ptr],byte 3 + jc prim_fade_90 + mov bp,pserr_wrong_arg_types + mov cx,2 + call get_pstack_tos + cmp dl,t_string + stc + jnz prim_fade_90 + push eax + mov dx,t_int + (t_int << 8) + call get_2args + pop edx + jc prim_fade_90 + + sub word [pstack_ptr],byte 3 + + mov bp,ax + mov ax,cx + lin2segofs edx,es,bx + call fade_one + + clc +prim_fade_90: + ret + + +prim_idle: + mov dx,t_int + (t_ptr << 8) + call get_2args + jnc prim_idle_10 + cmp dx,t_int + (t_none << 8) + stc + jnz prim_idle_90 +prim_idle_10: + sub word [pstack_ptr],byte 2 + mov byte [run_idle],0 + cmp dh,t_none ; undef + jz prim_idle_90 + push ecx + call lin2so + pop dword [idle_data] + mov [idle_data2],eax + mov byte [run_idle],1 + clc +prim_idle_90: + ret + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Helper function that covers common cases. + +; return eax as ptr on stack, returns undef if eax = 0 +pr_getptr_or_none: + mov dl,t_ptr + or eax,eax + jnz pr_getobj + mov dl,t_none + jmp pr_getobj + +; return eax as integer on stack +pr_getint: + mov dl,t_int + +; return eax as dl on stack +pr_getobj: + mov cx,[pstack_ptr] + inc cx + cmp [pstack_size],cx + mov bp,pserr_pstack_overflow + jc pr_getobj_90 + mov [pstack_ptr],cx + xor cx,cx + call set_pstack_tos +pr_getobj_90: + ret + + +; get ptr from stack as eax; if it is undef, don't return to function +pr_setptr_or_none: + mov dl,t_ptr + +; get obj from stack as eax; if it is undef, don't return to function +pr_setobj_or_none: + call get_1arg + jnc pr_setobj_20 + cmp dl,t_none + stc + jnz pr_setobj_10 + dec word [pstack_ptr] + clc + jmp pr_setobj_10 + +; get integer from stack as eax +pr_setint: + mov dl,t_int + +; get object with type dl from stack as eax +pr_setobj: + call get_1arg + jnc pr_setobj_20 +pr_setobj_10: + pop ax ; don't return to function that called us + ret +pr_setobj_20: + dec word [pstack_ptr] + pop cx ; put link to clc on stack + push word pr_setobj_30 + jmp cx +pr_setobj_30: + clc + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; ensure the cursor is always within the visible area +; +edit_align: + mov cx,[edit_width] + mov dx,cx + shr dx,1 + mov ax,[edit_cursor] + sub ax,[edit_shift] + cmp ax,dx + jg edit_align_50 + + sub ax,5 ; still 5 pixel away? + jge edit_align_90 + add [edit_shift],ax + jge edit_align_90 + and word [edit_shift],byte 0 + jmp edit_align_90 +edit_align_50: + sub cx,ax + sub cx,byte 5 ; still 5 pixel away? + jge edit_align_90 + sub [edit_shift],cx +edit_align_90: + ret + + + + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; es:bx string +; si ptr to char (rel. to es:bx) +; +; return: +; si points to prev char +; +; Changes no other regs. +; +utf8_prev: + push ax + or si,si + jz utf8_prev_90 +utf8_prev_50: + dec si + jz utf8_prev_90 + mov al,[es:bx+si] + shr al,6 + cmp al,2 + jz utf8_prev_50 +utf8_prev_90: + pop ax + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; es:bx string +; si ptr to char (rel. to es:bx) +; +; return: +; si points to next char +; +; Changes no other regs. +; +utf8_next: + push ax + cmp byte [es:bx+si],0 + jz utf8_next_90 +utf8_next_50: + inc si + mov al,[es:bx+si] + shr al,6 + cmp al,2 + jz utf8_next_50 +utf8_next_90: + pop ax + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; eax key (bits 0-23: key, 24-31: scan code) +; +edit_input: + mov edx,eax + shr edx,24 + and eax,1fffffh + les si,[edit_buf] + mov bx,si + + dec si +edit_input_10: + inc si + cmp byte [es:si],0 + jnz edit_input_10 + mov cx,si + sub cx,bx + ; cx: string length + + mov si,[edit_buf_ptr] + + cmp dl,keyLeft + jnz edit_input_20 + mov di,si + call utf8_prev + cmp di,si + jz edit_input_90 + mov [edit_buf_ptr],si + jmp edit_input_80 +edit_input_20: + cmp dl,keyRight + jnz edit_input_21 + mov di,si + call utf8_next + cmp di,si + jz edit_input_90 + mov [edit_buf_ptr],si + jmp edit_input_80 +edit_input_21: + cmp dl,keyEnd + jnz edit_input_22 + cmp byte [es:bx+si],0 + jz edit_input_90 + mov [edit_buf_ptr],cx + jmp edit_input_80 +edit_input_22: + cmp dl,keyHome + jnz edit_input_23 + or si,si + jz edit_input_90 + and word [edit_buf_ptr],byte 0 + jmp edit_input_80 +edit_input_23: + cmp dl,keyDel + jnz edit_input_30 +edit_input_24: + mov di,si + call utf8_next + cmp di,si + jz edit_input_90 +edit_input_25: + mov al,[es:bx+si] + mov [es:bx+di],al + inc si + inc di + or al,al + jnz edit_input_25 + jmp edit_input_80 +edit_input_30: + cmp eax,keyBS + jnz edit_input_35 + mov di,si + call utf8_prev + cmp di,si + jz edit_input_90 + mov [edit_buf_ptr],si + jmp edit_input_24 +edit_input_35: + + cmp eax,20h + jb edit_input_90 + + ; reject chars we can't display + pusha + push es + call char_width + or cx,cx + pop es + popa + jz edit_input_90 + + push cx + push bx + push si + call utf8_enc + pop si + pop bx + pop ax + + mov dx,[edit_buf_len] + sub dx,ax + sub dx,cx + jb edit_input_90 + cmp dx,1 + jb edit_input_90 + sub ax,[edit_buf_ptr] + add [edit_buf_ptr],cx + + ; ax: bytes to copy (excl. final 0) + ; cx: utf8 size + + push si + add si,ax + mov di,si + add di,cx + inc ax +edit_input_70: + mov dl,[es:bx+si] + mov [es:bx+di],dl + dec si + dec di + dec ax + jnz edit_input_70 + pop si + + mov di,utf8_buf +edit_input_75: + mov al,[di] + mov [es:bx+si],al + inc di + inc si + dec cx + jnz edit_input_75 + +edit_input_80: + mov si,[edit_buf_ptr] + mov al,0 + xchg al,[es:bx+si] + push ax + push si + push bx + push es + mov si,bx + call str_size + pop es + pop bx + pop si + pop ax + xchg al,[es:bx+si] + mov [edit_cursor],cx + + call edit_align + + call edit_redraw +edit_input_90: + ret + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +edit_redraw: + mov ax,[edit_x] + sub ax,[edit_shift] + mov [gfx_cur_x],ax + mov ax,[edit_y] + add ax,[edit_y_ofs] + mov [gfx_cur_y],ax + + les si,[edit_buf] +edit_redraw_20: + call utf8_dec + or eax,eax + jz edit_redraw_50 + push si + push es + call edit_char + pop es + pop si + jmp edit_redraw_20 +edit_redraw_50: + mov ax,[edit_x] + add ax,[edit_width] + sub ax,[gfx_cur_x] + jle edit_redraw_90 + + push word [edit_y] + pop word [gfx_cur_y] + mov dx,ax + imul ax,[pixel_bytes] + mov cx,[edit_height] + mov bx,[edit_width] + imul bx,[pixel_bytes] + les di,[edit_bg] + add di,4 + add di,bx + sub di,ax + call restore_bg +edit_redraw_90: + ret + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Write char at current cursor position. +; +; eax char +; [edit_bg] background pixmap +; +; return: +; cursor position gets advanced +; +edit_char: + push fs + + push word [clip_r] + push word [clip_l] + + push eax + + mov cx,[edit_x] + mov [clip_l],cx + add cx,[edit_width] + mov [clip_r],cx + + call find_char + + cmp byte [chr_width],0 + jz edit_char_80 + + les di,[edit_bg] + mov bx,[edit_width] + imul bx,[pixel_bytes] + add di,4 + mov ax,[edit_y_ofs] + imul bx + add di,ax + mov cx,[gfx_cur_x] + sub cx,[edit_x] + imul cx,[pixel_bytes] + add di,cx + + mov dx,[chr_width] + mov cx,[font_height] + + call restore_bg + +edit_char_80: + pop eax + + call char_xy + + pop word [clip_l] + pop word [clip_r] + +edit_char_90: + pop fs + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +edit_hide_cursor: + les di,[edit_bg] + add di,4 + mov ax,[edit_cursor] + sub ax,[edit_shift] + mov cx,ax + imul cx,[pixel_bytes] + add di,cx + add ax,[edit_x] + mov [gfx_cur_x],ax + push word [edit_y] + pop word [gfx_cur_y] + mov cx,[edit_height] + mov dx,1 + mov bx,[edit_width] + imul bx,[pixel_bytes] + call restore_bg + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +edit_show_cursor: + call screen_segs + + mov ax,[edit_cursor] + sub ax,[edit_shift] + add ax,[edit_x] + mov [gfx_cur_x],ax + push word [edit_y] + pop word [gfx_cur_y] + mov cx,[edit_height] +edit_show_cursor_10: + push cx + call goto_xy + call [setpixel_t] + pop cx + inc word [gfx_cur_y] + loop edit_show_cursor_10 + ret + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; es:si initial text +; +edit_init: + push fs + push es + pop fs + xor cx,cx + mov [edit_shift],cx + les di,[edit_buf] +edit_init_10: + fs lodsb + or al,al + jz edit_init_20 + stosb + inc cx + cmp cx,[edit_buf_len] + jb edit_init_10 + dec cx + dec di +edit_init_20: + mov byte [es:di],0 + mov [edit_buf_ptr],cx + + mov si,[edit_buf] + call str_size + mov [edit_cursor],cx + + call edit_align + + call edit_redraw + call edit_show_cursor +edit_init_90: + pop fs + ret + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; es:si parameter array +; +; note: no consistency checks done, es:si _must_ point to +; a valid array +; +edit_put_params: + push word [edit_buf_ptr] + pop word [es:si+2+5*5+1] + + push word [edit_cursor] + pop word [es:si+2+5*6+1] + + push word [edit_shift] + pop word [es:si+2+5*7+1] + + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; es:si parameter array +; +; return: +; CF invalid data +; +edit_get_params: + es lodsw + cmp ax,8 + jc edit_get_params_90 + + cmp byte [es:si+5*0],t_int + jnz edit_get_params_80 + push word [es:si+5*0+1] + pop word [edit_x] + + cmp byte [es:si+5*1],t_int + jnz edit_get_params_80 + push word [es:si+5*1+1] + pop word [edit_y] + + cmp byte [es:si+5*2],t_ptr + jnz edit_get_params_80 + push dword [es:si+5*2+1] + call lin2so + pop dword [edit_bg] + + cmp byte [es:si+5*3],t_string + jnz edit_get_params_80 + push dword [es:si+5*3+1] + call lin2so + pop dword [edit_buf] + + cmp byte [es:si+5*4],t_int + jnz edit_get_params_80 + push word [es:si+5*4+1] + pop word [edit_buf_len] + + cmp byte [es:si+5*5],t_int + jnz edit_get_params_80 + push word [es:si+5*5+1] + pop word [edit_buf_ptr] + + cmp byte [es:si+5*6],t_int + jnz edit_get_params_80 + push word [es:si+5*6+1] + pop word [edit_cursor] + + cmp byte [es:si+5*7],t_int + jnz edit_get_params_80 + push word [es:si+5*7+1] + pop word [edit_shift] + + les si,[edit_bg] + es lodsw + mov [edit_width],ax + es lodsw + mov [edit_height],ax + + mov cx,[font_height] + sub ax,cx + sar ax,1 + mov [edit_y_ofs],ax + + cmp word [edit_buf_len],byte 2 ; at least 1 char + jc edit_get_params_90 + + movzx eax,word [edit_width] + movzx ecx,word [edit_height] + mul ecx + cmp eax,10000h-20 + jae edit_get_params_80 ; to large: max 64k + + clc + jmp edit_get_params_90 + +edit_get_params_80: + stc +edit_get_params_90: + ret + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; basic graphics functions +; +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; map next window segment +; +inc_winseg: + push ax + mov al,[cs:mapped_window] + inc al + call set_win + pop ax + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; map window segment +; +; al = window segment +; +set_win: + cmp byte [cs:vbe_active],0 + jz set_win_90 + cmp [cs:mapped_window],al + jz set_win_90 + pusha + mov [cs:mapped_window],al + mov ah,[cs:window_inc] + mul ah + xchg ax,dx + mov ax,4f05h + xor bx,bx + cmp word [cs:window_seg_r],0 + jz set_win_50 + pusha + inc bx + int 10h + popa +set_win_50: + int 10h + popa +set_win_90: + ret + + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Go to current cursor position. +; +; return: +; di offset +; correct gfx segment is mapped +; +; Notes: +; - changes no regs other than di +; - does not require ds == cs +; +goto_xy: + push ax + push dx + mov ax,[cs:gfx_cur_y] + mov di,[cs:gfx_cur_x] + imul di,[pixel_bytes] + mul word [cs:screen_line_len] + add ax,di + adc dx,0 + push ax + xchg ax,dx + call set_win + pop di + pop dx + pop ax + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Set active color. +; +; eax color +; +; return: +; [gfx_color] color +; +; Changed registers: eax +; +setcolor: + call encode_color + mov [gfx_color],eax + ret + + +encode_color: + cmp byte [pixel_bits],16 + jnz encode_color_90 + push edx + xor edx,edx + shl eax,8 + shld edx,eax,5 + shl eax,8 + shld edx,eax,6 + shl eax,8 + shld edx,eax,5 + mov eax,edx + pop edx +encode_color_90: + ret + + +; ax palette index +; +; return: +; eax color +; +pal_to_color: + push fs + push si + lfs si,[gfx_pal] + add si,ax + add si,ax + add si,ax + mov eax,[fs:si] + bswap eax + shr eax,8 + pop si + pop fs + ret + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; draw a line +; +line: + xor eax,eax + xor ebx,ebx + inc ax + inc bx + mov esi,[line_x1] + sub esi,[line_x0] + jns line_10 + neg esi + neg eax +line_10: + mov ebp,[line_y1] + sub ebp,[line_y0] + jns line_20 + neg ebp + neg ebx +line_20: + call screen_segs + + xchg eax,ecx + mov eax,[screen_line_len] + imul ebx + xchg eax,edx + + mov eax,[line_y0] + push edx + imul dword [screen_line_len] + pop edx + xchg eax,edi + + mov eax,[line_x0] + imul eax,[pixel_bytes] + + add edi,eax + + cmp byte [pixel_bytes],1 + jbe line_25 + cmp byte [pixel_bytes],2 + jz line_23 + shl dword [line_x0],2 + shl dword [line_x1],2 + shl ecx,2 + jmp line_25 +line_23: + shl dword [line_x0],1 + shl dword [line_x1],1 + shl ecx,1 +line_25: + + ; es -> window + ; edi -> address + ; ecx -> d_x + ; edx -> d_y + + cmp esi,ebp + jl hline_40 + + or esi,esi + jz line_60 + + mov [line_tmp],esi + shr esi,1 + neg esi + + mov eax,[line_x1] + sub [line_x0],eax + +line_30: + call line_pp + + add edi,ecx + add [line_x0],ecx + jz line_60 + add esi,ebp + jnc line_30 + sub esi,[line_tmp] + add edi,edx + jmp line_30 + +hline_40: + or ebp,ebp + jz line_60 + + mov [line_tmp],ebp + shr ebp,1 + neg ebp + + mov eax,[line_y1] + sub [line_y0],eax + +line_50: + call line_pp + + add edi,edx + add [line_y0],ebx + jz line_60 + add ebp,esi + jnc line_50 + sub ebp,[line_tmp] + add edi,ecx + jmp line_50 +line_60: + ; now draw final point + + mov eax,[line_y1] + imul dword [screen_line_len] + add eax,[line_x1] + xchg eax,edi + + call line_pp + + ret + +line_pp: + mov eax,edi + shr eax,16 + call set_win + jmp [setpixel_t] + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Set pixel at es:di. +; +setpixel_8: + mov al,[gfx_color] + +setpixel_a_8: + mov [es:di],al + ret + +setpixel_16: + mov ax,[gfx_color] + +setpixel_a_16: + mov [es:di],ax + ret + +setpixel_32: + mov eax,[gfx_color] + +setpixel_a_32: + mov [es:di],eax + ret + + +; with transparency +setpixel_t_16: + mov ax,[gfx_color] + +setpixel_ta_16: + mov [es:di],ax + ret + +setpixel_t_32: + mov eax,[gfx_color] + +setpixel_ta_32: + cmp word [transp],0 + jz setpixel_a_32 + push ecx + mov ecx,[fs:di] + ror ecx,16 + ror eax,16 + call add_transp + rol ecx,8 + rol eax,8 + call add_transp + rol ecx,8 + rol eax,8 + call add_transp + mov [es:di],ecx + pop ecx + ret + +; cl, al -> cl +add_transp: + push eax + push ecx + movzx eax,al + movzx ecx,cl + sub ecx,eax + imul ecx,[transp] + sar ecx,8 + add ecx,eax + cmp ecx,0 + jge add_transp_10 + mov cl,0 + jmp add_transp_20 +add_transp_10: + cmp ecx,100h + jb add_transp_20 + mov cl,0ffh +add_transp_20: + mov [esp],cl + pop ecx + pop eax + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Get pixel from fs:si. +; +getpixel_8: + mov al,[fs:si] + ret + +getpixel_16: + mov ax,[fs:si] + ret + +getpixel_32: + mov eax,[fs:si] + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Initialize font. +; +; eax linear ptr to font header +; +font_init: + lin2segofs eax,es,bx + cmp dword [es:bx+foh_magic],0d2828e07h ; magic + jnz font_init_90 + mov ax,[es:bx+foh_entries] + mov dl,[es:bx+foh_height] + mov dh,[es:bx+foh_line_height] + or ax,ax + jz font_init_90 + or dx,dx + jz font_init_90 + mov [font_entries],ax + mov [font_height],dl + mov [font_line_height],dh + push es + push bx + pop dword [font] +font_init_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Write a string. '\n' is a line break. +; +; es:si ASCIIZ string +; +; return: +; cursor position gets advanced +; +; special chars: +; char_eot same as \x00 +; \x10 back to normal +; \x11 set alternative text color (gfx_color1) +; \x12 label start, no text output +; \x13 set link text color (gfx_color2); typically label end +; \x14 start page description +; +text_xy: + xor eax,eax + mov [last_label],ax + mov [cur_row],ax + and [txt_state],byte ~1 + + test byte [txt_state],2 + jz text_xy_05 + mov [row_start_seg],es + mov [row_start_ofs],si + mov [cur_row2],ax + mov [cur_link],ax + mov [sel_link],ax + mov [page_title],ax + push si + call utf8_dec + pop si + call is_eot + jz text_xy_05 + inc word [cur_row2] +text_xy_05: + push word [gfx_cur_x] +text_xy_10: + mov di,si + call utf8_dec + + call is_eot + jz text_xy_90 + + cmp word [line_wrap],byte 0 + jz text_xy_60 + + call is_space + jnz text_xy_60 + + push si + mov si,di + call word_width + pop si + add cx,[gfx_cur_x] + cmp cx,[line_wrap] + jbe text_xy_60 +text_xy_30: + call is_space + jnz text_xy_50 + + mov di,si + call utf8_dec + + call is_eot + jz text_xy_90 + jmp text_xy_30 +text_xy_50: + mov si,di + jmp text_xy_65 +text_xy_60: + cmp eax,0ah + jnz text_xy_70 +text_xy_65: + mov ax,[font_line_height] + add [gfx_cur_y],ax + pop ax + push ax + mov [gfx_cur_x],ax + inc word [cur_row] + mov dx,[max_rows] + mov ax,[cur_row] + or dx,dx + jz text_xy_67 + cmp ax,dx + jae text_xy_90 +text_xy_67: + test byte [txt_state],2 + jz text_xy_10 + cmp ax,max_text_rows + jae text_xy_10 + mov [cur_row2],ax + inc word [cur_row2] + add ax,ax + xchg ax,bx + mov [row_start_ofs + bx],si + jmp text_xy_10 +text_xy_70: + push si + push es + cmp eax,1fh + jae text_xy_80 + call text_special + jmp text_xy_81 +text_xy_80: + test byte [txt_state],1 + jnz text_xy_81 + call char_xy +text_xy_81: + pop es + pop si + jmp text_xy_10 +text_xy_90: + pop ax + push dword [gfx_color0] + pop dword [gfx_color] + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Handle special chars. +; +; eax char +; es:si ptr to next char +; +text_special: + cmp eax,10h + jnz text_special_20 + + and byte [txt_state],~1 + push eax + mov eax,[gfx_color0] + call setcolor + pop eax + jmp text_special_90 +text_special_20: + cmp eax,11h + jnz text_special_30 + + and byte [txt_state],~1 + push eax + mov eax,[gfx_color1] + call setcolor + pop eax + jmp text_special_90 +text_special_30: + cmp eax,12h + jnz text_special_40 + + or byte [txt_state],1 + mov [last_label],si + + jmp text_special_90 +text_special_40: + cmp eax,13h + jnz text_special_50 + + and byte [txt_state],~1 + + ; check for selected link + mov bx,[sel_link] + shl bx,3 ; sizeof_link = 8 + mov dx,[bx+link_list+li_text] + cmp si,dx + + push eax + mov eax,[gfx_color3] + jz text_special_45 + mov eax,[gfx_color2] +text_special_45: + call setcolor + pop eax + + test byte [txt_state],2 + jz text_special_90 + + mov bx,[cur_link] + cmp bx,link_entries + jae text_special_90 + inc word [cur_link] + shl bx,3 ; sizeof_link = 8 + add bx,link_list + push word [last_label] + pop word [bx+li_label] + mov [bx+li_text],si + push word [gfx_cur_x] + pop word [bx+li_x] + mov dx,[cur_row2] + sub dx,1 ; 0-- -> 0 + adc dx,0 + mov [bx+li_row],dx + + jmp text_special_90 +text_special_50: + cmp eax,14h + jnz text_special_60 + + mov [page_title],si + + jmp text_special_90 +text_special_60: + + +text_special_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; string width until end of next word +; +; es:si ASCIIZ string +; +; return: +; cx width +; +word_width: + push es + push si + push ax + + xor dx,dx + mov bl,0 + +word_width_10: + call utf8_dec + +word_width_20: + call is_eot + jz word_width_90 + + cmp eax,0ah + jz word_width_90 + + cmp eax,12h + jnz word_width_30 + mov bl,1 +word_width_30: + cmp eax,10h + jz word_width_40 + cmp eax,13h + jnz word_width_50 +word_width_40: + mov bl,0 +word_width_50: + + or bl,bl + jnz word_width_70 + + push eax + push bx + push dx + push si + push es + call char_width + pop es + pop si + pop dx + pop bx + pop eax + + add dx,cx + +word_width_70: + call is_space + jz word_width_10 + + call utf8_dec + + call is_space + jnz word_width_20 + +word_width_90: + mov cx,dx + + pop ax + pop si + pop es + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Test for white space (space or tab). +; +; eax char +; +; return: +; ZF 0 = no, 1 = yes +; +is_space: + cmp eax,20h + jz is_space_90 + cmp eax,9 +is_space_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Test for end of text. +; +; eax char +; +; return: +; ZF 0 = no, 1 = yes +; +is_eot: + or eax,eax + jz is_eot_90 + cmp eax,[char_eot] +is_eot_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Get string dimensions (in pixel). +; +; es:si ASCIIZ string +; +; return: +; cx width +; dx height +; +str_size: + xor cx,cx + xor dx,dx +str_size_20: + push cx + push dx + call str_len + xchg ax,cx + pop dx + pop cx + cmp ax,cx + jb str_size_40 + mov cx,ax +str_size_40: + inc dx + + ; suppress final line break + call utf8_dec + cmp eax,0ah + jnz str_size_60 + cmp byte [es:si],0 + jz str_size_80 +str_size_60: + or eax,eax + jz str_size_80 + cmp eax,[char_eot] + jz str_size_80 + jmp str_size_20 +str_size_80: + dec dx + mov ax,[font_line_height] + mul dx + mov dx,[font_height] + add dx,ax +str_size_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Get string length (in pixel). +; *** Use str_size instead. *** +; +; es:si ASCIIZ string +; +; return: +; cx width +; es:si points to string end or line break +; +; notes: +; - stops at linebreak ('\n') +; +str_len: + xor cx,cx +str_len_10: + mov di,si + call utf8_dec + or eax,eax + jz str_len_70 + cmp eax,[char_eot] + jz str_len_70 + cmp eax,0ah + jz str_len_70 + push cx + push si + push es + call char_width + pop es + pop si + pop ax + add cx,ax + jmp str_len_10 +str_len_70: + mov si,di + ret + + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Decode next utf8 char. +; +; es:si string +; +; return: +; eax char (invalid char: 0) +; +; Note: changes only: eax, si +; +utf8_dec: + xor eax,eax + es lodsb + cmp al,80h + jb utf8_dec_90 + + push cx + push edx + + xor edx,edx + xor cx,cx + mov dl,al + + cmp al,0c0h ; invalid + jb utf8_dec_70 + + inc cx ; 2 bytes + and dl,1fh + cmp al,0e0h + jb utf8_dec_10 + + inc cx ; 3 bytes + and dl,0fh + cmp al,0f0h + jb utf8_dec_10 + + inc cx ; 4 bytes + and dl,7 + cmp al,0f8h + jb utf8_dec_10 + + inc cx ; 5 bytes + and dl,3 + cmp al,0fch + jb utf8_dec_10 + + inc cx ; 6 bytes + and dl,1 + cmp al,0feh + jae utf8_dec_70 +utf8_dec_10: + es lodsb + cmp al,80h + jb utf8_dec_70 + cmp al,0c0h + jae utf8_dec_70 + and al,3fh + shl edx,6 + or dl,al + dec cx + jnz utf8_dec_10 + xchg eax,edx + jmp utf8_dec_80 + +utf8_dec_70: + xor eax,eax +utf8_dec_80: + pop edx + pop cx + +utf8_dec_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Encode utf8 char. +; +; eax char +; +; return: +; cx length +; utf8_buf char +; +utf8_enc: + mov si,utf8_buf + xor cx,cx + xor dx,dx + + cmp eax,80h + jae utf8_enc_10 + mov [si],al + inc si + jmp utf8_enc_80 +utf8_enc_10: + inc cx + cmp eax,800h + jae utf8_enc_20 + shl eax,21 + mov dl,6 + shld edx,eax,5 + shl eax,5 + jmp utf8_enc_60 +utf8_enc_20: + inc cx + cmp eax,10000h + jae utf8_enc_30 + shl eax,16 + mov dl,0eh + shld edx,eax,4 + shl eax,4 + jmp utf8_enc_60 +utf8_enc_30: + inc cx + cmp eax,200000h + jae utf8_enc_40 + shl eax,11 + mov dl,1eh + shld edx,eax,3 + shl eax,3 + jmp utf8_enc_60 +utf8_enc_40 + inc cx + cmp eax,4000000h + jae utf8_enc_50 + shl eax,6 + mov dl,3eh + shld edx,eax,2 + shl eax,2 + jmp utf8_enc_60 +utf8_enc_50: + inc cx + shl eax,1 + mov dl,7eh + shld edx,eax,1 + add eax,eax +utf8_enc_60: + mov bx,cx + mov [si],dl + inc si +utf8_enc_70: + mov dl,2 + shld edx,eax,6 + shl eax,6 + mov [si],dl + inc si + dec bx + jnz utf8_enc_70 +utf8_enc_80: + mov byte [si],0 + inc cx +utf8_enc_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Write a char at the current cursor position. +; +; eax char +; +; return: +; cursor position gets advanced +; +char_xy: + cmp eax,1fh ; \x1f looks like a space, but isn't + jnz char_xy_10 + mov al,' ' +char_xy_10: + call find_char + jc char_xy_90 + + test byte [txt_state],2 ; don't actually write + jnz char_xy_80 + + push word [gfx_cur_x] + push word [gfx_cur_y] + + mov cx,[chr_x_ofs] + add [gfx_cur_x],cx + + mov dx,[chr_y_ofs] + add [gfx_cur_y],dx + + call goto_xy + + call screen_segs + + lgs si,[font] + add si,[chr_bitmap] + + cmp byte [chr_real_width],0 + jz char_xy_70 + cmp byte [chr_real_height],0 + jz char_xy_70 + + xor dx,dx + xor bp,bp + +char_xy_20: + xor cx,cx +char_xy_30: + bt [gs:si],bp + jnc char_xy_40 + mov ax,[gfx_cur_x] + add ax,cx + cmp ax,[clip_r] + jge char_xy_40 + cmp ax,[clip_l] + jl char_xy_40 + call [setpixel_t] +char_xy_40: + inc bp + add di,[pixel_bytes] + jnc char_xy_50 + call inc_winseg +char_xy_50: + inc cx + cmp cx,[chr_real_width] + jnz char_xy_30 + + mov ax,[screen_line_len] + mov bx,[chr_real_width] + imul bx,[pixel_bytes] + sub ax,bx + add di,ax + jnc char_xy_60 + call inc_winseg +char_xy_60: + inc dx + cmp dx,[chr_real_height] + jnz char_xy_20 + +char_xy_70: + + pop word [gfx_cur_y] + pop word [gfx_cur_x] + +char_xy_80: + mov cx,[chr_width] + add [gfx_cur_x],cx + +char_xy_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Look for char in font. +; +; eax char +; +; return: +; CF 0 = found, 1 = not found +; [chr_*] updated +; +find_char: + and eax,1fffffh + cmp dword [font],byte 0 + stc + jz find_char_90 + + les bx,[font] + add bx,sizeof_font_header_t + mov cx,[font_entries] + +find_char_20: + mov si,cx + shr si,1 + + shl si,3 + mov edx,[es:bx+si+ch_c] + and edx,1fffffh ; 21 bits + cmp eax,edx + + jz find_char_80 + + jl find_char_50 + + add bx,si + test cl,1 + jz find_char_50 + add bx,sizeof_char_header_t +find_char_50: + shr cx,1 + jnz find_char_20 + + stc + jmp find_char_90 + +find_char_80: + mov dx,[es:bx+si+ch_ofs] + mov [chr_bitmap],dx + mov edx,[es:bx+si+ch_size] + + shr edx,5 + mov cl,dl + and cl,01fh + mov [chr_x_ofs],cl + + shr edx,5 + mov cl,dl + and cl,01fh + mov [chr_y_ofs],cl + + shr edx,5 + mov cl,dl + and cl,01fh + mov [chr_real_width],cl + + shr edx,5 + mov cl,dl + and cl,01fh + mov [chr_real_height],cl + + shr edx,5 + mov cl,dl + and cl,01fh + mov [chr_width],cl + + clc +find_char_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Get char width. +; +; eax char +; +; return: +; eax char +; cx char width +; +char_width: + push eax + cmp eax,1fh ; \x1f looks like a space, but isn't + jnz char_width_10 + mov al,' ' +char_width_10: + call find_char + mov cx,0 + jc char_width_90 + mov cx,[chr_width] +char_width_90: + pop eax + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Draw part of an image. +; +draw_image: + push gs + push fs + + mov es,[window_seg_w] + + lin2segofs dword [pcx_line_starts],gs,bp + + mov ax,[line_y0] + cmp ax,[image_height] + jae draw_image_90 + + mov bx,ax + add ax,[line_y1] ; length! + sub ax,[image_height] + jbe draw_image_10 + sub [line_y1],ax +draw_image_10: + shl bx,2 + add bp,bx + +draw_image_20: + call goto_xy + + lfs si,[gs:bp] + + mov cx,[line_x0] + neg cx + + ; draw one line +draw_image_30: + fs lodsb + + mov ah,0 + cmp al,0c0h + jb draw_image_70 + + ; repeat count + + and ax,3fh + mov dx,ax + fs lodsb + + add cx,dx + js draw_image_80 + jnc draw_image_40 + mov dx,cx + +draw_image_40: + mov bx,cx + sub bx,[line_x1] + jle draw_image_50 + sub dx,bx +draw_image_50: + or dx,dx + jz draw_image_80 + dec dx + cmp ax,[transparent_color] + jz draw_image_55 + cmp byte [pixel_bytes],1 + jbe draw_image_54 + push ax + call pal_to_color + call encode_color + call [setpixel_a] + pop ax + jmp draw_image_55 +draw_image_54: + mov [es:di],al +draw_image_55: + add di,[pixel_bytes] + jnc draw_image_50 + call inc_winseg + jmp draw_image_50 + +draw_image_70: + inc cx + cmp cx,byte 0 + jle draw_image_80 + cmp ax,[transparent_color] + jz draw_image_75 + cmp byte [pixel_bytes],1 + jbe draw_image_74 + call pal_to_color + call encode_color + call [setpixel_a] + jmp draw_image_75 +draw_image_74: + mov [es:di],al +draw_image_75: + add di,[pixel_bytes] + jnc draw_image_80 + call inc_winseg +draw_image_80: + cmp cx,[line_x1] + jl draw_image_30 + + inc word [gfx_cur_y] + + add bp,4 + dec word [line_y1] + jnz draw_image_20 + +draw_image_90: + pop fs + pop gs + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Get some memory for palette data +; +pal_init: + mov eax,300h + call calloc + push eax + call lin2so + pop dword [gfx_pal] + or eax,eax + stc + jz pal_init_90 + mov eax,300h + call calloc + push eax + call lin2so + pop dword [gfx_pal_tmp] + or eax,eax + stc + jz pal_init_90 + clc +pal_init_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Load palette data. +; +; cx number of palettes +; dx start +; +load_palette: + push fs + + cmp byte [pixel_bytes],1 + ja load_palette_90 + + cmp dx,100h + jae load_palette_90 + + mov ax,dx + add ax,cx + sub ax,100h + jbe load_palette_10 + sub cx,ax +load_palette_10: + or cx,cx + jz load_palette_90 + + mov ax,dx + add ax,dx + add ax,dx + + push dx + push cx + + ; vga function wants 6 bit values + + lfs si,[gfx_pal] + les di,[gfx_pal_tmp] + add si,ax + add di,ax + + imul cx,cx,3 + mov dx,di + push dx +load_palette_50: + fs lodsb + mov ah,0 + mul word [brightness] + shr ax,10 + stosb + loop load_palette_50 + + pop dx + pop cx + pop bx + + +%if 0 + mov si,dx + mov dx,3dah + cli +load_palette_60: + in al,dx + test al,8 + jnz load_palette_60 +load_palette_70: + in al,dx + test al,8 + jz load_palette_70 + cli + imul cx,cx,3 + mov dx,3c8h + xchg ax,bx + out dx,al + inc dx + es rep outsb + sti +%else + mov ax,1012h + int 10h +%endif + +load_palette_90: + pop fs + ret + + +; es:bx colors +; ax ref color +; +fade_in: + xor bp,bp + +fade_in_20: + push bx + push ax + + mov dx,3dah +fade_in_30: + in al,dx + test al,8 + jnz fade_in_30 +fade_in_40: + in al,dx + test al,8 + jz fade_in_40 + + pop ax + pop bx + + push bx + push ax + call fade_one + pop ax + pop bx + + add bp,4 + + cmp bp,100h + jbe fade_in_20 + + ret + + +; es:bx colors +; ax ref color +; bp step (0 - 100h) +; +fade_one: + push fs + + lfs si,[gfx_pal] + mov di,si + imul ax,ax,3 + add di,ax + + mov dx,3c8h + xor cx,cx +fade_one_30: + cmp byte [es:bx],0 + jz fade_one_70 + + mov al,cl + out dx,al + + inc dx + + mov al,[fs:di] + mov ah,[fs:si] + call fade_it + shr al,2 + out dx,al + + mov al,[fs:di+1] + mov ah,[fs:si+1] + call fade_it + shr al,2 + out dx,al + + mov al,[fs:di+2] + mov ah,[fs:si+2] + call fade_it + shr al,2 + out dx,al + + dec dx +fade_one_70: + inc bx + add si,3 + inc cx + cmp cx,100h + jb fade_one_30 + +fade_one_90: + pop fs + ret + + +; al old color +; ah new color +; bp step (0 - 100h) +; +; return: +; al color +fade_it: + push cx + push dx + push bp + + push ax + movzx ax,ah + mul bp + mov cx,ax + sub bp,100h + neg bp + pop ax + mov ah,0 + mul bp + add ax,cx + mov al,ah + + pop bp + pop dx + pop cx + ret + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +parse_img: + push fs + mov eax,[pcx_line_starts] + or eax,eax + jz parse_img_10 + call free +parse_img_10: + movzx eax,word [image_height] + shl eax,2 + call calloc + or eax,eax + stc + mov [pcx_line_starts],eax + jz parse_img_90 + lin2segofs eax,es,di + lfs si,[image_data] + + xor dx,dx ; y count + +parse_img_20: + xor cx,cx ; x count + mov [es:di],si + mov [es:di+2],fs + add di,4 +parse_img_30: + fs lodsb + cmp al,0c0h + jb parse_img_40 + and ax,3fh + inc si + add cx,ax + dec cx +parse_img_40: + inc cx + cmp cx,[image_width] + jb parse_img_30 + stc + jnz parse_img_90 ; no decoding break at line end? + + ; normalize fs:si + mov bp,si + and si,0fh + shr bp,4 + mov ax,fs + add ax,bp + mov fs,ax + + inc dx + cmp dx,[image_height] + jb parse_img_20 + +parse_img_90: + pop fs + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; cx colors +; dx src +; bx dst +; +tint: + push fs + + ; ensure we don't exceed bounds + cmp dx,100h + jae tint_90 + cmp bx,100h + jae tint_90 + + mov ax,dx + cmp dx,bx + jae tint_10 + mov ax,bx +tint_10: + add ax,cx + sub ax,100h + jb tint_20 + sub cx,ax +tint_20: + or cx,cx + jz tint_90 + + lfs si,[gfx_pal] + les di,[gfx_pal_tmp] + + imul ax,dx,3 + add si,dx + imul ax,bx,3 + add di,ax + imul cx,cx,3 + push ax + push cx + + xor bx,bx + +tint_40: + movzx ax,byte [gfx_cs_r + bx] + fs movzx bp,byte [si] + inc si + sub ax,bp + push bp + movzx dx,byte [gfx_cs_tint_r + bx] + imul dx + mov bp,0ffh ; 100 + idiv bp + pop bp + add ax,bp + jns tint_50 + xor ax,ax +tint_50: + or ah,ah + jz tint_60 + mov ax,0ffh +tint_60: + stosb + inc bx + cmp bx,3 + jb tint_70 + xor bx,bx +tint_70: + loop tint_40 + + pop cx + pop ax + + lfs si,[gfx_pal_tmp] + les di,[gfx_pal] + + add di,ax + add si,ax + fs rep movsb +tint_90: + pop fs + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Clip drawing area. +; +; [gfx_cur_x] left border +; [gfx_cur_y] top border +; [gfx_width] width +; [gfx_height] height +; +; return: +; CF 1 = empty area +; If CF = 0 Area adjusted to fit within [clip_*]. +; If CF = 1 Undefined values in [gfx_*]. +; +; Changed registers: - +; +clip_it: + pusha + + mov ax,[gfx_cur_x] + mov dx,[gfx_width] + mov cx,[clip_l] + add dx,ax + + sub ax,cx + jge clip_it_10 + add [gfx_width],ax + mov [gfx_cur_x],cx +clip_it_10: + sub dx,[clip_r] + jl clip_it_20 + sub [gfx_width],dx +clip_it_20: + cmp word [gfx_width],0 + jg clip_it_30 + mov word [gfx_width],0 + stc + jmp clip_it_90 +clip_it_30: + + mov ax,[gfx_cur_y] + mov dx,[gfx_height] + mov cx,[clip_t] + add dx,ax + + sub ax,cx + jge clip_it_40 + add [gfx_height],ax + mov [gfx_cur_y],cx +clip_it_40: + sub dx,[clip_b] + jl clip_it_50 + sub [gfx_height],dx +clip_it_50: + cmp word [gfx_height],0 + jg clip_it_90 + mov word [gfx_height],0 + stc + +clip_it_90: + popa + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; save a screen region +; +; dx,cx = width, height +; es:di = buffer +; +save_bg: + push fs + + push es + push di + + call goto_xy + + call screen_seg_r + + mov si,di + pop di + pop es + + or cx,cx + jz save_bg_90 + or dx,dx + jz save_bg_90 + + imul dx,[pixel_bytes] + +save_bg_20: + push dx +save_bg_30: + mov al,[fs:si] + inc si + jnz save_bg_40 + call inc_winseg +save_bg_40: + mov [es:di],al + inc di + jnz save_bg_50 + mov bp,es + add bp,1000h + mov es,bp +save_bg_50: + dec dx + jnz save_bg_30 + pop dx + mov ax,[screen_line_len] + sub ax,dx + add si,ax + jnc save_bg_60 + call inc_winseg +save_bg_60: + dec cx + jnz save_bg_20 + +save_bg_90: + pop fs + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Restore a screen region. +; +; dx,cx width, height +; bx bytes per line +; es:di buffer +; +; Does not change cursor positon. +; +restore_bg: + push fs + + push dword [gfx_cur] + + mov [gfx_width],dx + mov [gfx_height],cx + + mov ax,[gfx_cur_x] + mov cx,[gfx_cur_y] + + call clip_it + jc restore_bg_90 + + sub ax,[gfx_cur_x] + neg ax + mul word [pixel_bytes] + movzx ebp,ax + + sub cx,[gfx_cur_y] + neg cx + movzx ecx,cx + movzx ebx,bx + imul ecx,ebx + add ecx,ebp + + push es + push di + call so2lin + add [esp],ecx + call lin2so + pop di + pop es + + mov dx,[gfx_width] + mov cx,[gfx_height] + + push es + push di + + call goto_xy + + call screen_seg_w + + pop si + pop fs + + imul dx,[pixel_bytes] + +restore_bg_20: + push dx +restore_bg_30: + mov al,[fs:si] + inc si + jnz restore_bg_40 + mov bp,fs + add bp,1000h + mov fs,bp +restore_bg_40: + mov [es:di],al + inc di + jnz restore_bg_50 + call inc_winseg +restore_bg_50: + dec dx + jnz restore_bg_30 + pop dx + mov ax,[screen_line_len] + sub ax,dx + add di,ax + jnc restore_bg_60 + call inc_winseg +restore_bg_60: + mov ax,bx + sub ax,dx + add si,ax + jnc restore_bg_70 + mov bp,fs + add bp,1000h + mov fs,bp +restore_bg_70: + dec cx + jnz restore_bg_20 + +restore_bg_90: + pop dword [gfx_cur] + + pop fs + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Save a screen region to extended memory. +; +; dx,cx width, height +; edi buffer (linear address) +; +xsave_bg: + push edi + + call goto_xy + mov ax,[window_seg_w] + cmp word [window_seg_r],byte 0 + jz xsave_bg_10 + mov ax,[window_seg_r] +xsave_bg_10: + segofs2lin ax,di,esi + + pop edi + + or cx,cx + jz xsave_bg_90 + or dx,dx + jz xsave_bg_90 + + call real_to_pm + +xsave_bg_20: + push dx +xsave_bg_30: + mov al,[es:esi] + inc si + jnz xsave_bg_40 + call pm_to_real + call inc_winseg + call real_to_pm +xsave_bg_40: + mov [es:edi],al + inc edi + dec dx + jnz xsave_bg_30 + pop dx + mov ax,[screen_line_len] + sub ax,dx + add si,ax + jnc xsave_bg_60 + call pm_to_real + call inc_winseg + call real_to_pm +xsave_bg_60: + dec cx + jnz xsave_bg_20 + + call pm_to_real + +xsave_bg_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Restore a screen region from extended memory. +; +; dx,cx width, height +; bx bytes per line +; edi buffer (linear address) +; +; note: +; bx must be >= dx +; +; Does not change cursor positon. +; +xrestore_bg: + push dword [gfx_cur] + + mov [gfx_width],dx + mov [gfx_height],cx + + call clip_it + jc restore_bg_90 + + mov dx,[gfx_width] + mov cx,[gfx_height] + + push edi + + call goto_xy + segofs2lin word [window_seg_w],di,edi + + pop esi + + or cx,cx + jz xrestore_bg_90 + or dx,dx + jz xrestore_bg_90 + + call real_to_pm + +xrestore_bg_20: + push dx +xrestore_bg_30: + mov al,[es:esi] + inc esi + mov [es:edi],al + inc di + jnz xrestore_bg_50 + call pm_to_real + call inc_winseg + call real_to_pm +xrestore_bg_50: + dec dx + jnz xrestore_bg_30 + pop dx + mov ax,[screen_line_len] + sub ax,dx + add di,ax + jnc xrestore_bg_60 + call pm_to_real + call inc_winseg + call real_to_pm +xrestore_bg_60: + movzx eax,bx + sub ax,dx + add esi,eax + dec cx + jnz xrestore_bg_20 + + call pm_to_real + +xrestore_bg_90: + pop dword [gfx_cur] + + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Load screen segments. Write segment to es, read segment to fs. +; +; Modified registers: - +; +screen_segs: + call screen_seg_w + jmp screen_seg_r + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Load write segment to es. +; +; Modified registers: - +; +screen_seg_w: + mov es,[window_seg_w] + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; +; Load read segment to fs. +; +; Modified registers: - +; +screen_seg_r: + cmp word [window_seg_r],0 + jz screen_seg_r_10 + mov fs,[window_seg_r] + ret +screen_seg_r_10: + mov fs,[window_seg_w] + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; draw a filled rectangle +; +; dx, cx = width, height +; eax color +; bh,bl = bh -> bl +; bp = drawing mode +; 0: move, 1: add, 2,3: dto, except for bh (bh->bl) +; +fill_rect: + mov [gfx_width],dx + mov [gfx_height],cx + + call clip_it + jc fill_rect_90 + + mov dx,[gfx_width] + mov cx,[gfx_height] + + call goto_xy + + call screen_segs + + mov bp,[screen_line_len] + push dx + mov ax,dx + xor dx,dx + mul word [pixel_bytes] + sub bp,ax + pop dx + +fill_rect_20: + mov bx,dx +fill_rect_30: + call [setpixel_t] + add di,[pixel_bytes] + jnc fill_rect_60 + call inc_winseg +fill_rect_60: + dec bx + jnz fill_rect_30 + + add di,bp + jnc fill_rect_80 + call inc_winseg +fill_rect_80: + dec cx + jnz fill_rect_20 + +fill_rect_90: + ret + + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +new_int8: + pushad + push ds + push es + push fs + push gs + + push cs + pop ds + + mov al,20h + out 20h,al + + inc dword [int8_count] + + cmp byte [sound_playing],0 + jnz new_int8_10 + + mov ax,[sound_timer1] + out 40h,al + mov al,ah + out 40h,al + + jmp new_int8_90 + +new_int8_10: + +%if 0 + rdtsc + mov esi,[next_int] + mov edi,[next_int + 4] + sub esi,eax + sbb edi,edx + jnc new_int8_20 + + xor eax,eax + xor edx,edx + sub eax,esi + sbb edx,edi + + mov [tmp_var_0],eax + mov [tmp_var_1],edx +%endif + +new_int8_20: + rdtsc + mov edi,edx + mov esi,eax + + sub eax,[next_int] + sbb edx,[next_int + 4] + jb new_int8_20 + + add esi,[cycles_per_int] + adc edi,0 + mov [next_int],esi + mov [next_int + 4],edi + + mov si,[sound_start] + cmp si,[sound_end] + jz new_int8_25 + + les bx,[sound_buf] + mov dl,[es:bx+si] + + cmp dl,0ffh + jz new_int8_22 + + mov al,[sound_61] + out 61h,al + and al,0xfe + out 61h,al + + mov al,dl + out 42h,al + +new_int8_22: + inc si + cmp si,sound_buf_size + jb new_int8_23 + xor si,si +new_int8_23: + + mov [sound_start],si + +new_int8_25: + mov ax,[sound_timer1] + out 40h,al + mov al,ah + out 40h,al + + mov ax,[sound_timer0] + or ax,ax + jz new_int8_30 + add [sound_cnt0],ax + jnc new_int8_40 +new_int8_30: + push word 40h + pop es + inc dword [es:6ch] +new_int8_40: + + cmp byte [sound_int_active],0 + jnz new_int8_90 + + mov byte [sound_int_active],1 + + sti + + mov ax,[sound_end] + sub ax,[sound_start] + jnc new_int8_60 + add ax,sound_buf_size +new_int8_60: + cmp ax,160 + jae new_int8_80 + call mod_get_samples + +new_int8_80: + + mov byte [sound_int_active],0 +new_int8_90: + + pop gs + pop fs + pop es + pop ds + popad + + iret + +sound_init: + cmp byte [sound_ok],0 + jnz sound_init_90 + + call chk_tsc + jc sound_init_90 + + mov eax,ar_sizeof + call calloc + cmp eax,byte 1 + jc sound_init_90 + push eax + call lin2so + pop dword [mod_buf] + + call mod_init + + mov eax,sound_buf_size + call calloc + cmp eax,byte 1 + jc sound_init_90 + push eax + call lin2so + pop dword [sound_buf] + + xor eax,eax + mov [int8_count],eax + mov [sound_start],ax + mov [sound_end],ax + mov [sound_playing],al + mov [sound_int_active],al + + push ds + pop es + mov di,playlist + mov cx,playlist_entries * sizeof_playlist + rep stosb + + pushf + cli + + in al,61h + mov [sound_old_61],al + or al,3 + mov [sound_61],al + + mov al,92h + out 43h,al + + mov al,30h + out 43h,al + + xor ax,ax + out 40h,al + out 40h,al + + push word 0 + pop es + + push dword [es:8*4] + pop dword [sound_old_int8] + + push cs + push word new_int8 + pop dword [es:8*4] + + popf + + mov eax,[int8_count] +sound_init_40: + cmp eax,[int8_count] + jz sound_init_40 + + rdtsc + + mov edi,edx + mov esi,eax + + mov eax,[int8_count] + add eax,4 +sound_init_50: + cmp eax,[int8_count] + jnz sound_init_50 + + rdtsc + + sub eax,esi + sbb edx,edi + + shrd eax,edx,18 + adc eax,0 + mov [cycles_per_tt],eax + + mov [tmp_var_0],eax + mov [tmp_var_1],edx + + mov eax,16000 + call sound_setsample + + xor eax,eax + mov [next_int],eax + mov [next_int + 4],eax + + mov byte [sound_ok],1 +sound_init_90: + ret + + +sound_done: + cmp byte [sound_ok],0 + jz sound_done_90 + + pushf + cli + + mov al,[sound_old_61] + out 61h,al + + mov al,36h + out 43h,al + + xor ax,ax + out 40h,al + out 40h,al + + mov [sound_timer0],ax + mov [sound_timer1],ax + mov [sound_cnt0],ax + mov [sound_playing],al + + push word 0 + pop es + + push dword [sound_old_int8] + pop dword [es:8*4] + + mov byte [sound_ok],0 + + popf + + push dword [mod_buf] + call so2lin + pop eax + call free + + push dword [sound_buf] + call so2lin + pop eax + call free + +sound_done_90: + ret + + +; eax: new sample rate +sound_setsample: + cmp eax,20 + jae sound_setsample_20 + mov eax,20 +sound_setsample_20: + cmp eax,18000 + jbe sound_setsample_50 + mov eax,18000 +sound_setsample_50: + mov [sound_sample],eax + xchg eax,ecx + mov eax,1193180 + xor edx,edx + div ecx + mov [sound_timer0],ax + push eax + mul dword [cycles_per_tt] + mov [cycles_per_int],eax + + mov [tmp_var_2],eax + + pop eax + + ; 5/4 faster + imul eax,eax,4 + mov ecx,5 + div ecx + + mov [sound_timer1],ax + mov [tmp_var_3],eax + + pushf + cli + out 40h,al + mov al,ah + out 40h,al + popf +sound_setsample_90: + ret + +%if 0 +sound_test: + cmp dword [sound_x],0 + jz sound_test_80 + + call sound_init + jc sound_test_90 + + mov eax,16000 + call sound_setsample + + mov byte [sound_playing],1 + + jmp sound_test_90 + + + +sound_test_80: + call sound_done +sound_test_90: + ret +%endif + + +; mod player +%include "modplay.inc" + + +mod_init: + push ds + push dword [mod_buf] + pop si + pop ds + call init + clc + pop ds + ret + +mod_load: + push ds + push dword [mod_buf] + pop si + pop ds + call loadmod + pop ds + ret + +mod_play: + push ds + push dword [mod_buf] + pop si + pop ds + call playmod + pop ds + mov byte [sound_playing],1 + ret + +mod_playsample: + push ds + push dword [mod_buf] + pop si + pop ds + call playsamp + pop ds + mov byte [sound_playing],1 + ret + +mod_get_samples: + push ds + push dword [mod_buf] + pop si + pop ds + call play + mov dl,[si] + add si,ar_samps + push ds + pop fs + pop ds + + ; dl: 0/1 --> play nothing/play + sub dl,1 + + mov cx,num_samples + les bx,[sound_buf] + mov di,[sound_end] + cld + +mod_get_samples_20: + + fs lodsb + or al,dl ; 0ffh if we play nothing + mov [es:bx+di],al + inc di + cmp di,sound_buf_size + jb mod_get_samples_50 + xor di,di + +mod_get_samples_50: + + dec cx + jnz mod_get_samples_20 + mov [sound_end],di + +mod_get_samples_90: + ret + +mod_setvolume: + cmp byte [sound_ok],0 + jz mod_setvolume_90 + push ds + push dword [mod_buf] + pop si + pop ds + + mov dx,ax + xor ax,ax + or dx,dx + jz mod_setvolume_50 + sub ax,1 + sbb dx,0 + mov bx,100 + div bx +mod_setvolume_50: + mov bx,ax + xor ax,ax + mov cx,ax + dec ax + call setvol + + pop ds +mod_setvolume_90: + ret + + +; see if we have a time stamp counter +chk_tsc: + mov ecx,1 << 21 + pushfd + pushfd + pop eax + xor eax,ecx + push eax + popfd + pushfd + pop edx + popfd + xor eax,edx + cmp eax,ecx + stc + jz chk_tsc_90 + mov eax,1 + cpuid + test dl,1 << 4 + jnz chk_tsc_90 + stc +chk_tsc_90: + ret + + diff --git a/getx11font.c b/getx11font.c new file mode 100644 index 0000000..b0d4116 --- /dev/null +++ b/getx11font.c @@ -0,0 +1,712 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <getopt.h> +#include <iconv.h> +#include <errno.h> +#include <inttypes.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#include <X11/X.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +#define MAGIC 0xd2828e07 + +struct option options[] = { + { "verbose", 0, NULL, 'v' }, + { "font", 1, NULL, 'f' }, + { "add", 1, NULL, 'a' }, + { "add-text", 1, NULL, 't' }, + { "add-charset", 1, NULL, 'c' }, + { "line-height", 1, NULL, 'l' }, + { "prop", 1, NULL, 'p' }, + { "test", 0, NULL, 999 }, + { } +}; + +typedef struct { + unsigned size; + unsigned char *data; + unsigned real_size; +} file_data_t; + +typedef struct { + uint32_t magic; + uint16_t entries; + uint8_t height; + uint8_t line_height; +} font_header_t; + +typedef struct { + uint16_t ofs; + uint16_t c; + uint32_t size; +} char_header_t; + +typedef struct { + char *name; + XFontStruct *x; + unsigned used:1; /* font actually used */ +} font_t; + +typedef struct char_data_s { + struct char_data_s* next; + unsigned ok:1; /* char exists */ + int c; /* char (utf32) */ + int index; /* array index for font */ + font_t *font; /* pointer to font */ + int width; /* char width */ + int height; /* char (actually font) height */ + unsigned char *bitmap; /* char bitmap, width x height */ + int x_ofs; + int y_ofs; + int real_width; + int real_height; + char_header_t head; +} char_data_t; + +int opt_verbose = 0; +char *opt_file; +int opt_test = 0; +int opt_line_height = 0; +int opt_prop = 0; +int opt_spacing = 0; +int opt_space_width = 0; + +file_data_t font = {}; + +font_t font_list[16]; +int fonts; + +char_data_t *char_list; + +static char_data_t *add_char(int c); +static char_data_t *find_char(int c); +static void dump_char(char_data_t *cd); +static void dump_char_list(void); +static void sort_char_list(void); +static int char_sort(const void *a, const void *b); +static void locate_char(char_data_t *cd); +static int char_index(XFontStruct *xfont, int c); +static int empty_row(char_data_t *cd, int row); +static int empty_column(char_data_t *cd, int column); +static void add_bbox(char_data_t *cd); +static void make_prop(char_data_t *cd); +static void encode_chars(font_header_t *fh); +static void add_data(file_data_t *d, void *buffer, unsigned size); +static void write_data(char *name); + +int main(int argc, char **argv) +{ + Display *display; + XGCValues gcv; + GC gc1, gc2; + Pixmap pixmap; + XImage *xi; + XChar2b xc; + int i, j, k, font_width, font_height; + char *str, *str1; + char_data_t *cd; + iconv_t ic = (iconv_t) -1, ic2; + char obuf[4], ibuf[6]; + char obuf2[4*0x100], ibuf2[0x100]; + char *obuf_ptr, *ibuf_ptr; + size_t obuf_left, ibuf_left; + FILE *f; + font_header_t fh; + unsigned char uc; + + opterr = 0; + + while((i = getopt_long(argc, argv, "a:f:c:l:p:t:v", options, NULL)) != -1) { + switch(i) { + case 'f': + if(fonts < sizeof font_list / sizeof *font_list) { + font_list[fonts++].name = optarg; + } + break; + + case 'a': + str = optarg; + if(sscanf(str, "%i - %i%n", &i, &j, &k) == 2 && k == strlen(str)) { + if(i < 0 || j < 0 || j < i || j - i >= 0x10000) { + fprintf(stderr, "invalid char range spec: %s\n", str); + return 1; + } + while(i <= j) add_char(i++); + } + else { + i = strtol(str, &str1, 0); + if(*str1 || i < 0) { + fprintf(stderr, "invalid char number: %s\n", str); + return 1; + } + add_char(i); + } + break; + + case 'l': + str = optarg; + i = strtol(str, &str1, 0); + if(*str1 || i < 0) { + fprintf(stderr, "invalid line height: %s\n", str); + return 1; + } + opt_line_height = i; + break; + + case 'p': + str = optarg; + if(sscanf(str, "%i , %i%n", &i, &j, &k) == 2 && k == strlen(str)) { + opt_prop = 1; + opt_spacing = i; + opt_space_width = j; + } + else { + fprintf(stderr, "invalid spec: %s\n", str); + return 1; + } + break; + + case 'c': + ic2 = iconv_open("utf32le", optarg); + if(ic2 == (iconv_t) -1) { + fprintf(stderr, "don't know char set %s\ntry 'iconv --list'\n", optarg); + return 1; + } + ibuf_ptr = ibuf2; + ibuf_left = sizeof ibuf2; + obuf_ptr = obuf2; + obuf_left = sizeof obuf2; + for(j = 0; j < sizeof ibuf2; j++) ibuf2[j] = j; + iconv(ic2, &ibuf_ptr, &ibuf_left, &obuf_ptr, &obuf_left); + for(str = obuf2; str < obuf_ptr; str += 4) { + i = *(int *) str; + if(i >= 0x20) add_char(i); + } + iconv_close(ic2); + break; + + case 't': + if(ic == (iconv_t) -1) { + ic = iconv_open("utf32le", "utf8"); + if(ic == (iconv_t) -1) { + fprintf(stderr, "can't convert utf8 data\n"); + return 1; + } + } + if((f = fopen(optarg, "r"))) { + int ok; + + ibuf_left = 0; + while((i = fread(ibuf + ibuf_left, 1, sizeof ibuf - ibuf_left, f)) > 0) { + // fprintf(stderr, "ibuf_left = %d, fread = %d\n", ibuf_left, i); + ibuf_ptr = ibuf; + ibuf_left += i; + do { + obuf_ptr = obuf; + obuf_left = sizeof obuf; + k = iconv(ic, &ibuf_ptr, &ibuf_left, &obuf_ptr, &obuf_left); + // fprintf(stderr, "k = %d, errno = %d, ibuf_left = %d, obuf_left = %d\n", k, errno, ibuf_left, obuf_left); + if(k >= 0 || (k == -1 && errno == E2BIG)) { + ok = 1; + if(!obuf_left) { + i = *(int *) obuf; + if(i >= 0x20) { + // fprintf(stderr, "add char 0x%x\n", i); + add_char(i); + } + } + } + else { + ok = 0; + } + } + while(ok && ibuf_left); + if(k == -1 && errno == EILSEQ) { + perror("iconv"); + return 1; + } + if(ibuf_left) { + memcpy(ibuf, ibuf + sizeof ibuf - ibuf_left, ibuf_left); + } + } + fclose(f); + } + else { + perror(optarg); + return 1; + } + break; + + case 'v': + opt_verbose++; + break; + + case 999: + opt_test++; + break; + } + } + + argc -= optind; argv += optind; + + if(argc != 1) { + fprintf(stderr, + "Usage: getx11font [options] fontfile\n" + "Build font for boot loader using X11 fonts.\n" + " -a, --add=first[-last]\n\tAdd chars from this range.\n" + " -c, --add-charset=charset\n\tAdd all chars from this charset.\n" + " -f, --font=X11_font_spec\n\tUse this font.\n" + " -h, --help\n\tShow this help text.\n" + " -l, --line-height=n\n\tSet line height (default: font height).\n" + " -p, --prop=n1,n2\n\tFake proportionally spaced Font.\n\tn1: spacing between chars; n2: space (char U+0020) width\n" + " -t, --add-text=samplefile\n\tAdd all chars used in this file. File must be UTF-8 encoded.\n" + " -v, --verbose\n\tDump font info.\n" + ); + return 1; + } + + opt_file = argv[0]; + + if(ic != (iconv_t) -1) iconv_close(ic); + + /* use default char list */ + if(!char_list) for(i = 0x20; i <= 0x7f; i++) add_char(i); + + /* default font */ + if(!fonts) font_list[fonts++].name = "fixed"; + + sort_char_list(); + + if(!(display = XOpenDisplay(getenv("DISPLAY")))) { + return fprintf(stderr, "unable to open display\n"), 2; + } + + /* open all fonts */ + for(i = 0; i < fonts; i++) { + if(!(font_list[i].x = XLoadQueryFont(display, font_list[i].name))) { + fprintf(stderr, "Warning: no such font: %s\n", font_list[i].name); + } + } + + /* look for chars in fonts */ + for(cd = char_list; cd; cd = cd->next) locate_char(cd); + + /* get font heigth */ + for(font_height = 0, i = 0; i < fonts; i++) { + if(font_list[i].used) { + j = font_list[i].x->max_bounds.ascent + font_list[i].x->max_bounds.descent; + if(j > font_height) font_height = j; + } + } + + /* get font width */ + for(font_width = 0, cd = char_list; cd; cd = cd->next) { + if(cd->width > font_width) font_width = cd->width; + /* char height = font height */ + cd->height = font_height; + } + + printf("Font Size: %d x %d", font_width, font_height); + if(opt_line_height && opt_line_height != font_height) { + printf(", Line Height: %d", opt_line_height); + } + printf("\n"); + + if(font_width > 32 || font_height > 32) { + fprintf(stderr, "Font size too large (max 32 x 32).\n"); + return 8; + } + + if(!font_width || !font_height) { + fprintf(stderr, "Strange font.\n"); + return 8; + } + + /* now, render all chars */ + + pixmap = XCreatePixmap(display, DefaultRootWindow(display), font_width, font_height, 1); + + gcv.background = gcv.foreground = 0; + gcv.fill_style = FillSolid; + + gc1 = XCreateGC(display, pixmap, GCForeground | GCBackground | GCFillStyle, &gcv); + gcv.foreground = 1; + gc2 = XCreateGC(display, pixmap, GCForeground | GCBackground | GCFillStyle, &gcv); + + for(cd = char_list; cd; cd = cd->next) { + if(!cd->ok) continue; + xc.byte1 = cd->c >> 8; + xc.byte2 = cd->c; + + XSetFont(display, gc2, cd->font->x->fid); + + XFillRectangle(display, pixmap, gc1, 0, 0, font_width, font_height); + XDrawImageString16(display, pixmap, gc2, 0, cd->font->x->max_bounds.ascent, &xc, 1); + + xi = XGetImage(display, pixmap, 0, 0, font_width, font_height, 1, XYPixmap); + + cd->bitmap = calloc(cd->height * cd->width, 1); + for(k = 0, j = 0; j < cd->height; j++) { + for(i = 0; i < cd->width; i++) { + cd->bitmap[k++] = XGetPixel(xi, i, j); + } + } + + XDestroyImage(xi); + } + + XFreePixmap(display, pixmap); + XFreeGC(display, gc2); + XFreeGC(display, gc1); + + XCloseDisplay(display); + + for(cd = char_list; cd; cd = cd->next) add_bbox(cd); + + if(opt_prop) { + for(cd = char_list; cd; cd = cd->next) make_prop(cd); + } + + encode_chars(&fh); + + for(i = j = 0, cd = char_list; cd; cd = cd->next) { + if(!cd->ok) { + printf(i ? ", " : "Missing Chars: "); + printf("0x%04x", cd->c); + i = 1; + } + } + if(i) printf("\n"); + + add_data(&font, &fh, sizeof fh); + for(cd = char_list; cd; cd = cd->next) { + if(!cd->ok) continue; + add_data(&font, &cd->head, sizeof cd->head); + } + + i = 0; + for(cd = char_list; cd; cd = cd->next) { + if(!cd->ok) continue; + k = cd->real_width * cd->real_height; + for(uc = 0, i = j = 0; i < k; i++, j++) { + if(j == 8) { + add_data(&font, &uc, 1); + uc = 0; + j = 0; + } + if(cd->bitmap[i]) uc += (1 << j); + } + if(j) add_data(&font, &uc, 1); + } + + if(opt_verbose) dump_char_list(); + + write_data(opt_file); + + return 0; +} + + +char_data_t *add_char(int c) +{ + char_data_t *cd; + + if((cd = find_char(c))) return cd; + + cd = calloc(1, sizeof *cd); + cd->c = c; + cd->next = char_list; + + return char_list = cd; +} + + +char_data_t *find_char(int c) +{ + char_data_t *cd; + + for(cd = char_list; cd; cd = cd->next) { + if(cd->c == c) return cd; + } + + return NULL; +} + + +void dump_char(char_data_t *cd) +{ + int i, j; + unsigned char *p; + + if(!cd || !cd->ok) return; + + printf( + "Char 0x%04x\n Font: %s\n Size: %d x %d\n", + cd->c, cd->font->name, cd->width, cd->height + ); + + if(cd->bitmap) { + printf( + " Bitmap: %d x %d\n Offset: %d x %d\n", + cd->real_width, cd->real_height, cd->x_ofs, cd->y_ofs + ); + p = cd->bitmap; + for(j = 0; j < cd->height; j++) { + printf(" |"); + if(j < cd->y_ofs || j >= cd->y_ofs + cd->real_height) { + for(i = 0; i < cd->width; i++) printf("."); + } + else { + for(i = 0; i < cd->width; i++) { + if(i < cd->x_ofs || i >= cd->x_ofs + cd->real_width) { + printf("."); + } + else { + printf("%c", *p++ ? '#' : ' '); + } + } + } + printf("|\n"); + } + } + +} + + +void dump_char_list() +{ + char_data_t *cd; + + for(cd = char_list; cd; cd = cd->next) { + dump_char(cd); + } +} + + +void sort_char_list() +{ + char_data_t *cd; + unsigned u, len; + char_data_t **c_list; + + for(len = 0, cd = char_list; cd; cd = cd->next) len++; + + if(!len) return; + + c_list = calloc(len + 1, sizeof *c_list); + + for(u = 0, cd = char_list; cd; cd = cd->next, u++) c_list[u] = cd; + + qsort(c_list, len, sizeof *c_list, char_sort); + + for(u = 0; u < len; u++) { + c_list[u]->next = c_list[u + 1]; + } + + char_list = *c_list; + + free(c_list); +} + + +int char_sort(const void *a, const void *b) +{ + return (*(char_data_t **) a)->c - (*(char_data_t **) b)->c; +} + + +void locate_char(char_data_t *cd) +{ + int i, j; + XCharStruct *xc; + + for(i = 0; i < fonts; i++) { + if((j = char_index(font_list[i].x, cd->c)) >= 0) { + xc = font_list[i].x->per_char ? font_list[i].x->per_char + j : &(font_list[i].x->max_bounds); + if(xc && xc->width) { + cd->index = j; + cd->font = font_list + i; + cd->width = xc->width; + cd->ok = 1; + font_list[i].used = 1; + break; + } + } + } +} + + +int char_index(XFontStruct *xfont, int c) +{ + int i; + + if(!xfont || (c & ~0xffff)) return -1; + + if(!xfont->min_byte1 && !xfont->max_byte1) { + i = c - xfont->min_char_or_byte2; + if(i > (int) xfont->max_char_or_byte2) i = -1; + } + else { + i = ((c >> 8) - xfont->min_byte1) + * (xfont->max_char_or_byte2 - xfont->min_char_or_byte2 + 1) + + (c & 0xff) - xfont->min_char_or_byte2; + } + + return i; +} + + +int empty_row(char_data_t *cd, int row) +{ + unsigned char *p1, *p2; + + p2 = (p1 = cd->bitmap + row * cd->real_width) + cd->real_width; + while(p1 < p2) if(*p1++) return 0; + + return 1; +} + + +int empty_column(char_data_t *cd, int col) +{ + int i; + unsigned char *p; + + for(p = cd->bitmap + col, i = 0; i < cd->real_height; i++, p += cd->real_width) { + if(*p) return 0; + } + + return 1; +} + + +void add_bbox(char_data_t *cd) +{ + int i; + unsigned char *p1, *p2; + + if(!cd->ok) return; + + cd->real_width = cd->width; + cd->real_height = cd->height; + + if(opt_test) return; + + while(cd->real_height && empty_row(cd, cd->real_height - 1)) cd->real_height--; + + while(cd->real_height && empty_row(cd, 0)) { + cd->real_height--; + cd->y_ofs++; + memcpy(cd->bitmap, cd->bitmap + cd->real_width, cd->real_width * cd->real_height); + } + + while(cd->real_width && empty_column(cd, cd->real_width - 1)) { + cd->real_width--; + p2 = (p1 = cd->bitmap + cd->real_width) + 1; + for(i = 1; i < cd->real_height; i++, p1 += cd->real_width, p2 += cd->real_width + 1) { + memcpy(p1, p2, cd->real_width); + } + } + + while(cd->real_width && empty_column(cd, 0)) { + cd->real_width--; + cd->x_ofs++; + p2 = (p1 = cd->bitmap) + 1; + for(i = 0; i < cd->real_height; i++, p1 += cd->real_width, p2 += cd->real_width + 1) { + memcpy(p1, p2, cd->real_width); + } + } +} + + +/* + * Fake proprtionally spaced font from fixed size font. + */ +void make_prop(char_data_t *cd) +{ + if(!cd->ok) return; + + cd->x_ofs = opt_spacing; + cd->width = cd->x_ofs + (cd->real_width ?: opt_space_width); +} + + +void encode_chars(font_header_t *fh) +{ + int ofs; + char_data_t *cd; + + memset(fh, 0, sizeof *fh); + fh->magic = MAGIC; + fh->height = char_list->height; + fh->line_height = opt_line_height ?: fh->height; + + ofs = sizeof *fh; + + for(cd = char_list; cd; cd = cd->next) if(cd->ok) fh->entries++; + + ofs += fh->entries * sizeof cd->head; + + for(cd = char_list; cd; cd = cd->next) { + if(!cd->ok) continue; + memset(&cd->head, 0, sizeof cd->head); + cd->head.ofs = ofs; + cd->head.c = cd->c; + cd->head.size = + (((cd->c >> 16) & 0x1f) << 0) + + ((cd->x_ofs & 0x1f) << 5) + + ((cd->y_ofs & 0x1f) << 10) + + ((cd->real_width & 0x1f) << 15) + + ((cd->real_height & 0x1f) << 20) + + ((cd->width & 0x1f) << 25); + ofs += (cd->real_width * cd->real_height + 7) >> 3; + } +} + + +void add_data(file_data_t *d, void *buffer, unsigned size) +{ + if(!size || !d || !buffer) return; + + if(d->size + size > d->real_size) { + d->real_size = d->size + size + 0x1000; + d->data = realloc(d->data, d->real_size); + if(!d->data) d->real_size = 0; + } + + if(d->size + size <= d->real_size) { + memcpy(d->data + d->size, buffer, size); + d->size += size; + } + else { + fprintf(stderr, "Oops, out of memory? Aborted.\n"); + exit(10); + } +} + + +void write_data(char *name) +{ + FILE *f; + + f = strcmp(name, "-") ? fopen(name, "w") : stdout; + + if(!f) { + perror(name); + return; + } + + if(fwrite(font.data, font.size, 1, f) != 1) { + perror(name); exit(3); + } + + fclose(f); +} + + diff --git a/help2txt b/help2txt new file mode 100755 index 0000000..8a8b6c9 --- /dev/null +++ b/help2txt @@ -0,0 +1,78 @@ +#! /usr/bin/perl + +sub nospaces; + +if(!@ARGV) { + print "Usage: help2txt help_file\n" . + "Converts a help file from HTML to the format used by the boot loader.\n"; + exit; +} + +while(<>) { + s/\s*<\/?(hr|body|html|h\d+)\s*>//g; + s/\s*<!.*?>\s*//g; + s/<(em|strong)>/\x11/g; + s/<\/(em|strong)>/\x10/g; + while(/<a\s/) { + if(s/\<a\s+name=\"([^"]+)\">([^<]*)<\/a>\s*/\x04\x12$1\x14$2\x10/) { + if($anchor{$1}) { + die "line $.: anchor \"$1\" already exists\n"; + } + else { + $anchor{$1} = 1; + } + die "line $.: label \"$1\" too long (max. 32)\n" if length $1 > 32; + } + elsif(s/<a\s+href=\"#([^"]+)\">([^<]*)<\/a>/"\x12" . $1 . "\x13" . nospaces($2) . "\x10"/e) { + $ref{$1}++; + die "line $.: label \"$1\" too long (max. 32)\n" if length $1 > 32; + } + else { + die "line $.: invalid 'A' element\n"; + } + } + + $txt .= $_; +} + +$txt =~ s/\n( +)(?!\n)/"\n<!" . length($1) . ">"/seg; +$txt =~ s/\s+/ /sg; +$txt =~ s/\s*<br>\s*/\n/sg; +$txt =~ s/<!(\d+)>/" " x $1/seg; +$txt =~ s/(\x14.*?\x10)\s*/$1/sg; +$txt =~ s/\s*(\x04|$)/$1/sg; + +print $txt, "\x00"; + +$ref{help}++; + +for (keys %anchor) { + if(!$ref{$_}) { + $err = 1; + print STDERR "\"$_\" never referenced\n" + } +} + +for (keys %ref) { + if(!$anchor{$_}) { + $err = 1; + print STDERR "\"$_\" never defined\n" + } +} + +warn "*** inconsistencies detected ***\n" if $err; + + +# \x1f looks like a space but is not a space. This is useful +# to prevent automatic line breaks. +sub nospaces +{ + local $_; + + $_ = shift; + + s/\s/\x1f/g; + + $_ +} + @@ -0,0 +1,80 @@ +#! /usr/bin/perl + +use Encode; +use Getopt::Long; + +sub get_table; +sub do_enc; + +$opt_all = 0; +$opt_enc = undef; + +GetOptions( + 'all' => \$opt_all, + 'enc=s' => \$opt_enc +); + +$keytable = shift; + +@us_map{get_table "us"} = () unless $opt_all; +@map = get_table $keytable; + +for (keys %us_map) { + delete $us_map{$_} if /\[\s*0x56/; +} + + +print "/keymap.$keytable [\n"; +for (@map) { + print $_ unless exists $us_map{$_}; +} +print "] def\n"; + + +sub get_table +{ + local $_; + my ($kt, $map_idx, @map, @psmap, $x, $n, $s, $a); + + $kt = shift; + + open F, "loadkeys -m $kt |"; + while(<F>) { + $map_idx = 0 if /u_short/; + if(/u_short\s+plain_map\[/) { $map_idx = 1; $key_idx = 0 } + if(/u_short\s+shift_map\[/) { $map_idx = 2; $key_idx = 0 } + if(/u_short\s+altgr_map\[/) { $map_idx = 3; $key_idx = 0 } + if($map_idx) { + while(/(0xf\S{3}),/g) { + $x = $1; + $map[$key_idx][0] = $key_idx; + $map[$key_idx][$map_idx] = hex($x) & 0xff if $x =~ /0xf[0b]/; + $key_idx++; + } + } + } + close F; + + for (@map) { + ($n, $s, $a) = ($_->[1], $_->[2], $_->[3]); + $a = 0 if $a == $n || $a == $s; + if($n || $s || $a) { + push @psmap, sprintf(" [ 0x%02x 0x%02x 0x%02x 0x%02x ]\n", $_->[0], do_enc($n), do_enc($s), do_enc($a)); + } + } + + @psmap; +} + + +sub do_enc +{ + my ($c); + + $c = shift; + + return $c unless $opt_enc; + + return unpack("V", encode("utf32le", decode($opt_enc, chr($c)))); +} + diff --git a/kroete.inc b/kroete.inc new file mode 100644 index 0000000..8f2d939 --- /dev/null +++ b/kroete.inc @@ -0,0 +1,100 @@ +; es:si pointer to data +; bx == 0 forward != 0 backward +kroete: + mov fs,[window_seg_w] + mov ax,[window_seg_r] + or ax,ax + jnz sul1 + mov ax,[window_seg_w] +sul1: mov gs,ax + mov di,[cs:screen_width] + shr di,1 + imul di,[cs:pixel_bytes] + mov ax,[cs:screen_height] + shr ax,1 + mul word [cs:screen_line_len] + add di,ax + adc dx,byte 0 + mov ax,dx + call set_win + call kr_getpixel + or bx,bx + jnz sul3 + lea bp,[si+16384] +sul: mov bl,[es:si] + rol bl,2 + call doit + rol bl,2 + call doit + rol bl,2 + call doit + rol bl,2 + call doit + inc si + cmp si,bp + jnz sul + call kr_putpixel + ret +sul3: lea bp,[si-1] + add si,16383 +sul4: mov bl,[es:si] + xor bl,0xaa + call doit + ror bl,2 + call doit + ror bl,2 + call doit + ror bl,2 + call doit + dec si + cmp si,bp + jnz sul4 + call kr_putpixel + ret +doit: + push ecx + call kr_getpixel + mov edx,ecx + pop ecx + call kr_putpixel + mov ecx,edx + mov dl,bl + and dl,3 + jnz doit1 + sub di,[cs:pixel_bytes] + jnc doit4 +doit5: sbb al,0 + jmp set_win +doit1: dec dl + jnz doit2 + sub di,[cs:screen_line_len] + jc doit5 +doit4: ret +doit2: dec dl + jnz doit3 + add di,[cs:pixel_bytes] + jnc doit4 +doit6: adc al,0 + jmp set_win +doit3: add di,[cs:screen_line_len] + jc doit6 + ret + +kr_getpixel: + cmp byte [cs:pixel_bytes],1 + ja kr_getpixel_10 + mov cl,[fs:di] + ret +kr_getpixel_10: + mov cx,[fs:di] + ret + +kr_putpixel: + cmp byte [cs:pixel_bytes],1 + ja kr_putpixel_10 + mov [gs:di],cl + ret +kr_putpixel_10: + mov [gs:di],cx + ret + diff --git a/mk_vocabulary b/mk_vocabulary new file mode 100755 index 0000000..b335598 --- /dev/null +++ b/mk_vocabulary @@ -0,0 +1,144 @@ +#! /usr/bin/perl + +# Ensure that both mkbootmsg.c & bincode.asm talk about the same thing. + +@callback = qw ( + KeyEvent MenuInit InfoBoxInit InfoBoxDone + ProgressInit ProgressDone ProgressUpdate + PasswordInit PasswordDone + Timeout Timer +); + +@primary = qw ( + [ ] def if ifelse loop repeat for forall exit return array get put length + dup pop exch rot roll over index exec + add sub mul div mod neg abs min max and or xor not shl shr + eq ne gt ge lt le + trace dtrace + malloc free memsize dumpmem + gettype settype + screen.size image.colors + moveto currentpoint lineto setcolor currentcolor putpixel getpixel + setfont currentfont fontheight strsize show + image loadpalette tint settintcolor setpalette getpalette + settransparentcolor + savescreen restorescreen + fillrect + snprintf + edit.init edit.done edit.input edit.showcursor edit.hidecursor + updatedisk rmoveto bootloader + strstr + + sound.getvolume sound.setvolume + sound.getsamplerate sound.setsamplerate + sound.play sound.done + mod.load mod.play mod.playsample + + settextwrap currenttextwrap + seteotchar currenteotchar + settextcolors currenttextcolors + setmaxrows currentmaxrows + formattext + gettextrows setstartrow + getlinks + setlink currentlink + getlink + lineheight + currenttitle + + videomodes getvideomode + xsavescreen + + usleep + time + setbrightness currentbrightness + fadein fade + idle + image.size + + bootdrive reloadfs usernote eject poweroff + + getinfo + + getbyte putbyte getdword putdword + findfile + + setmode currentmode findmode + colorbits + + setimage currentimage + + settransparency currenttransparency + +); + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +sub canon_name; + +if($ARGV[0] eq '-a') { + printf "cb_functions\t\tequ %u\n", @callback + 0; + printf "prim_functions\t\tequ %u\n\n", @primary + 3; + + $i = 0; + for (@callback) { + $c = canon_name $_; + $s = ""; + $s .= "\t" if length $c < 3; + $s .= "\t" if length $c < 11; + print "cb_$c$s\tequ $i\n"; + $i++; + } + + print "\n%macro\t\t\tprim_jump_table 0\n"; + print "jt_p_none\t\tdw 0\t\t\t; 00h\njt_p_code\t\tdw 0\t\t\t; 01h\njt_p_ret\t\tdw 0\t\t\t; 02h\n"; + $i = 3; + for (@primary) { + $c = canon_name $_; + $s = ""; + $s .= "\t" if length $c < 3; + $s .= "\t" if length $c < 11; + $t = ""; + $t .= "\t" if length $_ < 8; + print "jt_p_$c$s\tdw prim_$c$t\t; "; + printf "%02xh\n", $i++ + } + print "%endmacro\n" +} + +if($ARGV[0] eq '-c') { + print "typedef enum {\n"; + print " p_none,\n p_code,\n p_ret"; + for (@primary) { $c = canon_name $_; print ",\n p_$c" } + print "\n} prim_t;\n\n"; + + print "struct {\n type_t type;\n unsigned value;\n char *name;\n} prim_names[] = {\n"; + + for (@callback) { + print " { t_none, 0, \"$_\" },\n" + } + + print " { t_prim, p_code, \"{\" },\n"; + print " { t_prim, p_ret, \"{\" }"; + + for (@primary) { + $c = canon_name $_; + print ",\n { t_prim, p_$c, \"$_\" }" + } + + print "\n};\n" +} + + +sub canon_name +{ + local $_ = shift; + + $_ = 'astart' if $_ eq '['; + $_ = 'aend' if $_ eq ']'; + tr/.//d; + + return $_ +} + + diff --git a/mkbootmsg.c b/mkbootmsg.c new file mode 100644 index 0000000..2fac4fd --- /dev/null +++ b/mkbootmsg.c @@ -0,0 +1,1897 @@ +/* + * Create a boot loader graphics file. + * + */ + +#define _GNU_SOURCE + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <getopt.h> +#include <inttypes.h> +#include <ctype.h> +#include <iconv.h> + +#include "bincode.h" + +#define MAGIC 0xb2d97f00 +#define VERSION 5 +#define DICT_SIZE 1000 + +#define MAX_INCLUDE 10 + +typedef struct { + uint32_t magic_id; + uint8_t version; + uint8_t res_1; + uint8_t res_2; + uint8_t res_3; + uint32_t bincode; + uint32_t bincode_size; + uint32_t bincode_crc; + uint32_t dict; + uint32_t code; + uint32_t code_size; +} file_header_t; + +typedef struct { + unsigned size; + unsigned char *data; + unsigned real_size; + unsigned char *ptr; + char *name; + int line; +} file_data_t; + +struct option options[] = { + { "config", 1, NULL, 'c' }, + { "info", 0, NULL, 'i' }, + { "log", 0, NULL, 'l' }, + { "help", 0, NULL, 'h' }, + { } +}; + +// max. 16 +// Keep in sync with bincode.asm! +typedef enum { + t_none, t_int, t_unsigned, t_bool, t_string, t_code, t_ret, t_prim, + t_sec, t_dict_idx, t_array, t_end, t_ptr, + t_skip = 15 /* special, for internal use */ +} type_t; + +// for log file +static char *type_name[16] = { + "none", "int", "uint", "bool", "str", "code", "ret", "prim", + "sec", "dict", "arr", "end", "ptr", "", "", "" +}; + +typedef struct { + char *name; + type_t type; + int line; + int del, ref, ref_idx, ref_ind, def, def_idx, def_ind, ref0, ref0_idx; + union { + unsigned u; + unsigned char *p; + } value; +} dict_t; + +typedef struct { + char *name; + type_t type; + unsigned ofs; + unsigned size; + int line, incl_level; + union { + unsigned u; + unsigned char *p; + } value; + unsigned char *enc; +} code_t; + +void help(void); +file_data_t read_file(char *name); +int is_pcx(file_data_t *fd); +void fix_pal(unsigned char *pal, unsigned shade1, unsigned shade2, unsigned char *rgb); +void write_data(char *name); +void add_data(file_data_t *d, void *buffer, unsigned size); +code_t *new_code(void); +dict_t *new_dict(void); +unsigned number(char *value); +void hexdump(file_data_t *fd, unsigned ofs, int len); +void show_info(char *name); +int get_hex(char *s, int len, unsigned *val); +char *utf32_to_utf8(int u8); +char *next_word(char **ptr); +void parse_comment(char *comment, file_data_t *incl); +int find_in_dict(char *name); +int translate(int pass); +void encode_dict(void); +void parse_config(char *name, char *log_file); +void optimize_dict(FILE *lf); +unsigned skip_code(unsigned pos); +unsigned next_code(unsigned pos); +int optimize_code(FILE *lf); +int optimize_code1(FILE *lf); +int optimize_code2(FILE *lf); +int optimize_code3(FILE *lf); +int optimize_code4(FILE *lf); +int optimize_code5(FILE *lf); +int optimize_code6(FILE *lf); +int optimize_code7(FILE *lf); +void log_dict(FILE *lf); +void log_code(FILE *lf); +void log_cline(FILE *lf); +void decompile(unsigned char *data, unsigned size); + +/* dummy function to make ld fail */ +extern void wrong_struct_size(void); + +int config_ok = 0; + +file_header_t header = {}; + +file_data_t pscode = {}; +file_data_t dict_file = {}; + +dict_t *dict = NULL; +unsigned dict_size = 0; +unsigned dict_max_size = 0; + +code_t *code = NULL; +unsigned code_size = 0; +unsigned code_max_size = 0; + +int number_err = 0; +// current config line +int line = 1; + +int verbose = 0; +int optimize = 0; +int opt_force = 0; + +char *lib_path[2] = { NULL, "/usr/share/gfxboot" }; + +// initial vocabulary (note: "{" & "}" are special) +#include "vocabulary.h" + +int main(int argc, char **argv) +{ + int i; + char *config_file = NULL, *log_file = NULL; + int opt_info = 0; + + if(sizeof (file_header_t) != 32) { + fprintf(stderr, "file_header_t has wrong size: %d\n", sizeof (file_header_t)); + wrong_struct_size(); + return 1; + } + + opterr = 0; + + while((i = getopt_long(argc, argv, "c:fhiL:l:Ov", options, NULL)) != -1) { + switch(i) { + case 'c': + config_file = optarg; + break; + + case 'f': + opt_force = 1; + break; + + case 'i': + opt_info = 1; + break; + + case 'l': + log_file = optarg; + break; + + case 'L': + lib_path[0] = optarg; + break; + + case 'O': + optimize = 1; + break; + + case 'v': + verbose++; + break; + + default: + help(); + return 0; + } + } + + argc -= optind; argv += optind; + + if(config_file && argc == 1) { + parse_config(config_file, log_file); + write_data(*argv); + return 0; + } + + if(opt_info && argc == 1) { + show_info(*argv); + return 0; + } + + help(); + + return 1; +} + + +void help() +{ + fprintf(stderr, "%s", + "mkbootmsg: Usage mkbootmsg [options] out_file\n" + " Options are:\n" + " -c config_file, --config config_file\n" + " Create a boot message file using this configuration.\n" + " -l log_file, --log log_file\n" + " Write log to this file.\n" + " -i, --info\n" + " Show info about file.\n" + " -L\n" + " Search path for file read.\n" + " -O\n" + " Optimize code.\n" + " -h, --help\n" + " Show this text.\n" + ); +} + + +file_data_t read_file(char *name) +{ + file_data_t fd = { }; + FILE *f; + unsigned u; + char *s; + + if(!name) return fd; + + f = fopen(name, "r"); + if(!f) { + for(u = 0; u < sizeof lib_path / sizeof *lib_path; u++) { + if(lib_path[u]) { + asprintf(&s, "%s/%s", lib_path[u], name); + f = fopen(s, "r"); + if(f) { + fd.name = s; + break; + } + else { + free(s); + } + } + } + } + else { + fd.name = strdup(name); + } + + if(!f) { perror(name); return fd; } + + if(fseek(f, 0, SEEK_END)) { + perror(name); + exit(30); + } + + fd.size = fd.real_size = ftell(f); + + if(fseek(f, 0, SEEK_SET)) { + perror(name); + exit(30); + } + + if(fd.size) { + fd.ptr = fd.data = malloc(fd.size); + if(!fd.data) { + fprintf(stderr, "malloc failed\n"); + exit(30); + } + } + + if(fread(fd.data, 1, fd.size, f) != fd.size) { + perror(name); + exit(30); + } + + fclose(f); + + return fd; +} + + +int is_pcx(file_data_t *fd) +{ + if(!fd->data || fd->size < 0x381) return 0; + if( + fd->data[0] != 10 || + fd->data[1] != 5 || + fd->data[2] != 1 || + fd->data[3] != 8 || + fd->data[fd->size - 0x301] != 12 + ) return 0; + + return 1; +} + + +void write_data(char *name) +{ + FILE *f; + unsigned ofs; + file_data_t fd = {}; + + f = strcmp(name, "-") ? fopen(name, "w") : stdout; + + if(!f) { + perror(name); + return; + } + + // first, fix all offsets + + ofs = sizeof header; + + header.bincode = ofs; + header.bincode_size = sizeof bincode_data; + ofs += sizeof bincode_data; + + if(dict_file.data) { + header.dict = ofs; + ofs += dict_file.size; + } + + if(pscode.data) { + header.code = ofs; + header.code_size = pscode.size; + ofs += pscode.size; + } + + // then, put everything together + + add_data(&fd, &header, sizeof header); + + add_data(&fd, bincode_data, sizeof bincode_data); + + add_data(&fd, dict_file.data, dict_file.size); + + add_data(&fd, pscode.data, pscode.size); + + // now write everything + + if(fwrite(fd.data, fd.size, 1, f) != 1) { + perror(name); exit(3); + } + + fclose(f); +} + + +void add_data(file_data_t *d, void *buffer, unsigned size) +{ + ssize_t ofs = 0; + + if(!size || !d || !buffer) return; + + if(d->ptr && d->data) ofs = d->ptr - d->data; + + if(d->size + size > d->real_size) { + d->real_size = d->size + size + 0x1000; + d->data = realloc(d->data, d->real_size); + if(!d->data) d->real_size = 0; + } + + if(d->size + size <= d->real_size) { + memcpy(d->data + d->size, buffer, size); + d->size += size; + } + else { + fprintf(stderr, "Oops, out of memory? Aborted.\n"); + exit(10); + } + + if(d->ptr && d->data) d->ptr = d->data + ofs; +} + + +code_t *new_code() +{ + if(code_size >= code_max_size) { + code_max_size += 10; + code = realloc(code, code_max_size * sizeof * code); + memset(code + code_size, 0, (code_max_size - code_size) * sizeof * code); + } + + return code + code_size++; +} + + + +dict_t *new_dict() +{ + if(dict_size >= dict_max_size) { + dict_max_size += 10; + dict = realloc(dict, dict_max_size * sizeof *dict); + memset(dict + dict_size, 0, (dict_max_size - dict_size) * sizeof *dict); + } + + return dict + dict_size++; +} + + +unsigned number(char *value) +{ + char *s; + unsigned u; + + u = strtoul(value, &s, 0); + + if(*s) { + fprintf(stderr, "Line %d: \"%s\" is not a number\n", line, value); + exit(1); + } + + return u; +} + + +void hexdump(file_data_t *fd, unsigned ofs, int len) +{ + unsigned u, p; + char s[17]; + char ind[] = " "; + int i; + + if(!len || !fd) return; + + if(len < 0 || ofs + len > fd->size) { + printf("invalid data range: %d bytes at 0x%x\n", len, ofs); + } + + p = ofs; + u = ofs & ~0xf; + + memset(s, ' ', 16); + s[16] = 0; + + if(u < p) { + printf("%s%05x ", ind, u); + i = (p - u) * 3; + if(i > 8 * 3) i++; + while(i--) printf(" "); + } + + while(p < ofs + len) { + s[p & 15] = (fd->data[p] >= 0x20 && fd->data[p] <= 0x7e) ? fd->data[p] : '.'; + if(!(p & 15)) { + printf("%s%05x ", ind, p); + } + if(!(p & 7) && (p & 15)) printf(" "); + printf("%02x ", fd->data[p]); + if(!(++p & 15)) { + printf(" %s\n", s); + } + } + + if(p & 15) { + s[p & 15] = 0; + if(!(p & 8)) printf(" "); + printf("%*s %s\n", 3 * (16 - (p & 15)), "", s); + } + + +} + + +void show_info(char *name) +{ + unsigned ofs = 0; + file_data_t fd; + unsigned u; + + fd = read_file(name); + + if(fd.size >= sizeof header) { + memcpy(&header, fd.data, sizeof header); + ofs += sizeof header; + } + + if(header.magic_id != MAGIC) { + fprintf(stderr, "No mkbootmsg file.\n"); + return; + } + + if(header.version != VERSION) { + fprintf(stderr, "Version %u not supported.\n", header.version); + return; + } + + if(header.bincode && header.bincode_size) { + printf("%u bytes ia32 code:\n", header.bincode_size); + if(verbose >= 2) hexdump(&fd, header.bincode, header.bincode_size); + printf("\n"); + } + + if(header.dict && header.code) { + u = header.code - header.dict; + printf("dictionary: %d bytes at 0x%x:\n", u, header.dict); + hexdump(&fd, header.dict, u); + printf("\n"); + } + + if(header.code && header.code_size) { + printf("%u bytes code:\n", header.code_size); + if(verbose >= 1) hexdump(&fd, header.code, header.code_size); + printf("\n"); + decompile(fd.data + header.code, header.code_size); + printf("\n"); + } +} + + +/* + * Convert hex number of excatly len bytes. + */ +int get_hex(char *s, int len, unsigned *val) +{ + unsigned u; + char s2[len + 1]; + + if(!s || !len) return 0; + strncpy(s2, s, len); + s2[len] = 0; + + u = strtoul(s2, &s, 16); + if(!*s) { + if(val) *val = u; + return 1; + } + + return 0; +} + + +char *utf32_to_utf8(int u8) +{ + static char buf[16]; + static iconv_t ic = (iconv_t) -1; + char *ibuf, *obuf; + size_t obuf_left, ibuf_left; + int i; + + *buf = 0; + + if(ic == (iconv_t) -1) { + ic = iconv_open("utf8", "utf32le"); + if(ic == (iconv_t) -1) { + fprintf(stderr, "Error: can't convert utf8 data.\n"); + exit(1); + } + } + + ibuf = (char *) &u8; + obuf = buf; + ibuf_left = 4; + obuf_left = sizeof buf - 1; + + i = iconv(ic, &ibuf, &ibuf_left, &obuf, &obuf_left); + + if(i >= 0) { + i = sizeof buf - 1 - obuf_left; + buf[i] = 0; + } + else { + fprintf(stderr, "Warning: failed to convert 0x%x to utf8.\n", u8); + } + + return buf; +} + + +char *next_word(char **ptr) +{ + char *s, *start, *utf8; + int is_str, is_comment; + static char word[1024]; + int i, n; + char qc = 0; + + s = *ptr; + + *word = 0; + + while(isspace(*s)) if(*s++ == '\n') line++; + + if(!*s) { + *ptr = s; + return word; + } + + start = s; + + qc = *start; + is_str = qc == '"' || qc == '\'' ? 1 : 0; + is_comment = qc == '%' ? 1 : 0; + + if(is_comment) { + while(*s && *s != '\n') s++; + } + else if(is_str) { + *word = *s++; + for(n = 1; n < sizeof word - 1; n++) { + if(!*s) break; + if(*s == qc) { s++; break; } + if(*s == '\\') { + s++; + switch(*s) { + case 0: + word[n++] = '\\'; + break; + + case 'n': + word[n] = '\n'; + break; + + case 't': + word[n] = '\t'; + break; + + case '0': + if( + s[0] >= '0' && s[0] <= '7' && + s[1] >= '0' && s[1] <= '7' && + s[2] >= '0' && s[2] <= '7' + ) { + word[n] = ((s[0] - '0') << 6) + ((s[1] - '0') << 3) + (s[2] - '0'); + s += 2; + } + else { + word[n] = *s; + } + break; + + case 'x': + if(get_hex(s + 1, 2, &i)) { + s += 2; + word[n] = i; + } + else { + word[n++] = '\\'; + word[n] = *s; + } + break; + + case 'u': + if(get_hex(s + 1, 4, &i)) { + s += 4; + utf8 = utf32_to_utf8(i); + while(*utf8) word[n++] = *utf8++; + n--; + } + else { + word[n++] = '\\'; + word[n] = *s; + } + break; + + case 'U': + if(get_hex(s + 1, 8, &i)) { + s += 8; + utf8 = utf32_to_utf8(i); + while(*utf8) word[n++] = *utf8++; + n--; + } + else { + word[n++] = '\\'; + word[n] = *s; + } + break; + + default: + word[n] = *s; + } + s++; + } + else { + word[n] = *s++; + } + } + word[n] = 0; + } + else { + while(!isspace(*s)) s++; + } + + if(!is_str) { + n = s - start; + if(n >= sizeof word) n = sizeof word - 1; + strncpy(word, start, n); + word[n] = 0; + } + + *ptr = s; + + return word; +} + + +void parse_comment(char *comment, file_data_t *incl) +{ + char t[5][100]; + int n; + + n = sscanf(comment, " %99s %99s %99s %99s %99s", t[0], t[1], t[2], t[3], t[4]); + + if(!n) return; + + if(n == 2 && !strcmp(t[0], "include")) { + *incl = read_file(t[1]); + if(!incl->data) exit(18); + add_data(incl, "", 1); + fprintf(stderr, "Including \"%s\"\n", incl->name); + return; + } +} + + +int find_in_dict(char *name) +{ + int i; + + for(i = 0; i < dict_size; i++) { + if(dict[i].name && !strcmp(name, dict[i].name)) return i; + } + + return -1; +} + + +unsigned usize(unsigned u) +{ + if(u >> 24) return 4; + if(u >> 16) return 3; + if(u >> 8) return 2; + if(u) return 1; + + return 0; +} + + +unsigned isize(int i) +{ + if(i == 0) return 0; + if(i >= -0x80 && i <= 0x7f) return 1; + if(i >= -0x8000 && i <= 0x7fff) return 2; + if(i >= -0x800000 && i <= 0x7fffff) return 3; + + return 4; +} + + +int translate(int pass) +{ + int i; + code_t *c; + unsigned u0, u1, u2; + unsigned ofs = 0; + int changed = 0; + + if(pass == 0) { + changed = 1; + for(i = 0; i < code_size; i++) { + c = code + i; + + c->ofs = ofs; + + switch(c->type) { + case t_skip: + c->size = 0; + break; + + case t_int: + case t_unsigned: + u0 = isize(c->value.u); + u1 = usize(c->value.u); + u2 = u0; + if(u1 < u0) { + c->type = t_unsigned; + u2 = u1; + } + c->size = u2 + 1; + c->enc = malloc(c->size); + c->enc[0] = c->type + (u2 << 4); + if(u2) memcpy(c->enc + 1, &c->value.u, u2); + break; + + case t_string: + u1 = strlen(c->value.p) + 1; + u0 = usize(u1); + c->size = u1 + u0 + 1; + c->enc = malloc(c->size); + c->enc[0] = c->type + (u0 << 4) + 0x80; + memcpy(c->enc + 1, &u1, u0); + memcpy(c->enc + 1 + u0, c->value.p, u1); + break; + + case t_code: + c->size = 5; + break; + + case t_ret: + case t_end: + c->size = 1; + c->enc = malloc(c->size); + c->enc[0] = c->type; + break; + + case t_none: + case t_bool: + case t_sec: + case t_prim: + case t_dict_idx: + u0 = usize(c->value.u); + c->size = u0 + 1; + c->enc = malloc(c->size); + c->enc[0] = c->type + (u0 << 4); + if(u0) memcpy(c->enc + 1, &c->value.u, u0); + break; + + default: + fprintf(stderr, "Internal oops %d: type %d not allowed\n", __LINE__, c->type); + exit(8); + } + + ofs += c->size; + } + } + else { + for(i = 0; i < code_size; i++) { + c = code + i; + + if(c->ofs != ofs) changed = 1; + c->ofs = ofs; + + if(c->type == t_code) { + u0 = c->value.u; + if(u0 >= code_size) { + fprintf(stderr, "Internal error %d\n", __LINE__); + exit(11); + } + u1 = usize(code[u0].ofs); + if(c->size != u1 + 1) changed = 1; + c->size = u1 + 1; + if(c->enc) free(c->enc); + c->enc = malloc(c->size); + c->enc[0] = c->type + (u1 << 4); + if(u1) memcpy(c->enc + 1, &code[u0].ofs, u1); + } + + ofs += c->size; + } + } + + return changed; +} + + +void encode_dict() +{ + unsigned u; + int i; + + if(dict_size == 0 || dict_size > 0xffff) { + fprintf(stderr, "Internal oops %d\n", __LINE__); + exit(6); + } + + add_data(&dict_file, &dict_size, 4); + + u = 0; + + for(i = 0; i < dict_size; i++) { + if(dict[i].type == t_none || dict[i].type == t_prim) continue; + add_data(&dict_file, &i, 2); + add_data(&dict_file, &dict[i].type, 1); + add_data(&dict_file, &dict[i].value.u, 4); + u++; + } + + dict_file.data[2] = u; + dict_file.data[3] = u >> 8; +} + + +void parse_config(char *name, char *log_file) +{ + char *word; + file_data_t cfg[MAX_INCLUDE]; + file_data_t incl; + int i, j; + unsigned u; + dict_t *d; + code_t *c, *c1; + char *s; + FILE *lf = NULL; + int incl_level = 0; + + cfg[incl_level] = read_file(name); + add_data(&cfg[incl_level], "", 1); + + if(!cfg[incl_level].ptr || !*cfg[incl_level].ptr) { + fprintf(stderr, "Empty config file!\n"); + exit(1); + } + + if(log_file && *log_file) lf = fopen(log_file, "w"); + + header.magic_id = MAGIC; + header.version = VERSION; + + // setup initial vocabulary + for(i = 0; i < sizeof prim_names / sizeof *prim_names; i++) { + d = new_dict(); + d->type = prim_names[i].type; + d->value.u = prim_names[i].value; + d->name = prim_names[i].name; + } + + while(*cfg[incl_level].ptr || incl_level) { + if(!*cfg[incl_level].ptr) { + incl_level--; + line = cfg[incl_level].line; + } + word = next_word((char **) &cfg[incl_level].ptr); + if(!word || !*word) continue; + + if(word[0] == '%') { + if(word[1] == '%') { + incl.ptr = NULL; + parse_comment(word + 2, &incl); + if(incl.ptr) { + if(incl_level == MAX_INCLUDE - 1) { + fprintf(stderr, "Error: include level exceeded\n"); + exit(17); + } + else { + cfg[incl_level].line = line; + cfg[++incl_level] = incl; + line = 1; + } + } + } + continue; + } + + if(verbose >= 2) printf(">%s< (%d)\n", word, line); + + c = new_code(); + c->line = line; + c->incl_level = incl_level; + + if(*word == '"') { + c->type = t_string; + c->value.p = strdup(word + 1); + } + else if(*word == '\'') { + c->type = t_int; + c->value.u = word[1]; + asprintf(&c->name, "%s'", word); + } + else if(*word == '/') { + c->name = strdup(word + 1); + + c->type = t_dict_idx; + + if((i = find_in_dict(word + 1)) == -1) { + d = new_dict(); + d->type = t_none; + d->value.u = 1; // mark as defined + d->name = strdup(word + 1); + c->value.u = dict_size - 1; + } + else { + if(dict[i].type == t_none && !dict[i].value.u) { + dict[i].value.u = 1; // mark as defined + } + c->value.u = i; + } + } + else if(!strcmp(word, "{")) { + c->type = t_code; + c->name = strdup(word); + } + else if(!strcmp(word, "}")) { + c->type = t_ret; + c->name = strdup(word); + for(c1 = c; c1 >= code; c1--) { + if(c1->type == t_code && !c1->value.u) { + // point _after_ "}" + c1->value.u = c - code + 1; + break; + } + } + if(c1 < code) { + fprintf(stderr, "Syntax error: no matching \"{\" for \"}\" in line %d\n", line); + exit(10); + } + } + else { + c->name = strdup(word); + + i = find_in_dict(word); + + if(i == -1) { + u = strtoul(word, &s, 0); + if(*s) { + d = new_dict(); + d->type = t_none; + d->name = strdup(word); + c->type = t_sec; + c->value.u = dict_size - 1; + } + else { + c->type = t_int; + c->value.u = u; + } + } + else { + c->type = t_sec; + c->value.u = i; + } + } + } + + // add a final 'end' + c = new_code(); + c->type = t_end; + c->name = "end"; + + // check vocabulary + for(i = j = 0; i < dict_size; i++) { + if( + dict[i].type == t_none && !dict[i].value.u && + i >= sizeof prim_names / sizeof *prim_names /* callback functions need not be defined */ + ) { + if(!j) fprintf(stderr, "Undefined words:"); + else fprintf(stderr, ","); + fprintf(stderr, " %s", dict[i].name); + j = 1; + } + } + if(j) { + fprintf(stderr, "\n"); + if(!opt_force) exit(10); + } + + if(optimize) { + if(lf) fprintf(lf, "# searching for unused code:\n"); + for(i = 0; i < 64; i++) { + if(verbose && lf) fprintf(lf, "# pass %d\n", i + 1); + if(!optimize_code(lf)) break; + } + if(lf) fprintf(lf, "# %d optimization passes\n", i + 1); + if(i) { + if(lf) fprintf(lf, "# searching for unused dictionary entries:\n"); + optimize_dict(lf); + } + } + + // now translate to byte code + for(i = 0; i < 20; i++) { + if(!translate(i)) break; + } + if(lf) fprintf(lf, "# %d encoding passes\n", i + 1); + if(i == 20) { + fprintf(stderr, "Oops, code translation does not converge.\n"); + exit(7); + } + + // store it + for(i = 0; i < code_size; i++) { + if((!code[i].enc || !code[i].size) && code[i].type != t_skip) { + fprintf(stderr, "Internal oops %d\n", __LINE__); + exit(8); + } + add_data(&pscode, code[i].enc, code[i].size); + } + + // now encode the dictionary + encode_dict(); + + log_code(lf); + log_dict(lf); + + if(lf) fclose(lf); +} + + +/* + * Remove deleted dictionary entries. + */ +void optimize_dict(FILE *lf) +{ + int i; + int old_ofs, new_ofs; + + for(old_ofs = new_ofs = 0; old_ofs < dict_size; old_ofs++) { + if(dict[old_ofs].del) continue; + if(old_ofs != new_ofs) { + if(verbose && lf) fprintf(lf, "# rename %d -> %d\n", old_ofs, new_ofs); + dict[new_ofs] = dict[old_ofs]; + for(i = 0; i < code_size; i++) { + if( + ( + code[i].type == t_sec || + code[i].type == t_dict_idx + ) && + code[i].value.u == old_ofs + ) { + code[i].value.u = new_ofs; + } + } + } + new_ofs++; + } + if(lf && new_ofs != old_ofs) { + fprintf(lf, "# new dictionary size %d (%d - %d)\n", new_ofs, old_ofs, old_ofs - new_ofs); + } + + dict_size = new_ofs; +} + + +/* + * Skip deleted code. + */ +unsigned skip_code(unsigned pos) +{ + while(pos < code_size && code[pos].type == t_skip) pos++; + + return pos; +} + + +/* + * Return next instruction. + */ +unsigned next_code(unsigned pos) +{ + if((pos + 1) >= code_size) return pos; + + return skip_code(++pos); +} + + +int optimize_code(FILE *lf) +{ + unsigned i; + int changed, ind = 0; + code_t *c; + + for(i = 0; i < dict_size; i++) { + dict[i].def = dict[i].def_idx = + dict[i].ref = dict[i].ref_idx = + dict[i].ref0 = dict[i].ref0_idx = 0; + } + + for(i = 0; i < code_size; i++) { + c = code + i; + + switch(c->type) { + case t_code: + ind++; + break; + + case t_ret: + if(!ind) { + fprintf(stderr, "Warning: nesting error at line %d\n", c->line); + } + ind--; + break; + + case t_sec: + if(c->value.u < dict_size) { + dict[c->value.u].ref++; + dict[c->value.u].ref_idx = i; + dict[c->value.u].ref_ind = ind; + if(ind == 0 && !dict[c->value.u].ref0) { + dict[c->value.u].ref0 = 1; + dict[c->value.u].ref0_idx = i; + } + } + break; + + case t_dict_idx: + if(c->value.u < dict_size) { + dict[c->value.u].def++; + dict[c->value.u].def_idx = i; + dict[c->value.u].def_ind = ind; + } + break; + + default: + break; + } + } + + changed = 1; + + optimize_code1(lf) || + optimize_code2(lf) || + optimize_code3(lf) || + optimize_code4(lf) || + optimize_code5(lf) || + optimize_code6(lf) || + optimize_code7(lf) || + (changed = 0); + + return changed; +} + + +/* + * Find references to primary words. + */ +int optimize_code1(FILE *lf) +{ + unsigned i, j; + int changed = 0; + code_t *c; + + for(i = 0; i < dict_size; i++) { + if( + i < sizeof prim_names / sizeof *prim_names && + !dict[i].del && + dict[i].def == 0 && + dict[i].ref && + dict[i].type == t_prim + ) { + if(verbose && lf) fprintf(lf, "# replacing %s\n", dict[i].name); + for(j = 0; j < code_size; j++) { + c = code + j; + if(c->type == t_sec && c->value.u == i) { + c->type = dict[i].type; + c->value.u = dict[i].value.u; + } + } + + changed = 1; + } + } + + return changed; +} + + +/* + * Remove things like + * + * /foo 123 def + * /foo "abc" def + * /foo /bar def + * + * if foo is unused. + */ +int optimize_code2(FILE *lf) +{ + unsigned i, j; + int changed = 0; + code_t *c0, *c1, *c2; + + for(i = 0; i < dict_size; i++) { + if( + i >= sizeof prim_names / sizeof *prim_names && + !dict[i].del && + !dict[i].ref && + dict[i].def == 1 && + dict[i].type == t_none + ) { + c0 = code + (j = dict[i].def_idx); + c1 = code + (j = next_code(j)); + c2 = code + (j = next_code(j)); + + if( + c0->type == t_dict_idx && + c0->value.u == i && + ( + c1->type == t_none || + c1->type == t_int || + c1->type == t_unsigned || + c1->type == t_bool || + c1->type == t_string || + c1->type == t_dict_idx || + c1->type == t_ptr + ) && + c2->type == t_prim && + c2->value.u == p_def + ) { + if(verbose && lf) fprintf(lf, "# defined but unused: %s (index %d)\n", dict[i].name, i); + if(verbose && lf) fprintf(lf, "# deleting code: %d - %d\n", dict[i].def_idx, j); + c0->type = c1->type = c2->type = t_skip; + dict[i].del = 1; + + changed = 1; + } + } + } + + return changed; +} + + +/* + * Remove things like + * + * /foo { ... } def + * + * if foo is unused. + */ +int optimize_code3(FILE *lf) +{ + unsigned i, j, k; + int changed = 0; + code_t *c0, *c1; + + for(i = 0; i < dict_size; i++) { + if( + i >= sizeof prim_names / sizeof *prim_names && + !dict[i].del && + !dict[i].ref && + dict[i].def == 1 && + dict[i].type == t_none + ) { + c0 = code + (j = dict[i].def_idx); + c1 = code + next_code(j); + + if(c1 == c0) continue; + + if( + c0->type == t_dict_idx && + c0->value.u == i && + c1->type == t_code && + code[j = skip_code(c1->value.u)].type == t_prim && + code[j].value.u == p_def && + j > dict[i].def_idx + ) { + if(verbose && lf) fprintf(lf, "# defined but unused: %s (index %d)\n", dict[i].name, i); + if(verbose && lf) fprintf(lf, "# deleting code: %d - %d\n", dict[i].def_idx, j); + for(k = dict[i].def_idx; k <= j; k++) code[k].type = t_skip; + dict[i].del = 1; + + changed = 1; + } + } + } + + return changed; +} + + + +/* + * Find unused dictionary entries. + */ +int optimize_code4(FILE *lf) +{ + unsigned i; + int changed = 0; + + for(i = 0; i < dict_size; i++) { + if( + i >= sizeof prim_names / sizeof *prim_names && + !dict[i].del && + !dict[i].ref && + !dict[i].def + ) { + if(verbose && lf) fprintf(lf, "# unused: %s (index %d)\n", dict[i].name, i); + + dict[i].del = 1; + + changed = 1; + } + } + + return changed; +} + + +/* + * Replace references to constant global vars. + */ +int optimize_code5(FILE *lf) +{ + unsigned i, j, k; + int changed = 0; + code_t *c, *c0, *c1, *c2; + char *s; + + for(i = 0; i < dict_size; i++) { + if( + i >= sizeof prim_names / sizeof *prim_names && + !dict[i].del && + dict[i].def == 1 && + dict[i].def_ind == 0 && + ( + !dict[i].ref0 || + dict[i].ref0_idx > dict[i].def_idx + ) && + dict[i].type == t_none + ) { + c0 = code + (j = dict[i].def_idx); + c1 = code + (j = next_code(j)); + c2 = code + (j = next_code(j)); + + if( + c0->type == t_dict_idx && + c0->value.u == i && + ( + c1->type == t_none || + c1->type == t_int || + c1->type == t_unsigned || + c1->type == t_bool + ) && + c2->type == t_prim && + c2->value.u == p_def + ) { + if(verbose && lf) fprintf(lf, "# global constant: %s (index %d)\n", dict[i].name, i); + if(verbose && lf) fprintf(lf, "# replacing %s with %s\n", dict[i].name, c1->name); + for(k = 0; k < code_size; k++) { + c = code + k; + if(c->type == t_sec && c->value.u == i) { + c->type = c1->type; + c->value = c1->value; + if(c->type == t_int || c->type == t_unsigned) { + asprintf(&s, "%s # %s", c1->name, c->name); + free(c->name); + c->name = s; + } + else if(c->type == t_bool) { + asprintf(&s, "%s # %s", c->value.u ? "true" : "false", c->name); + free(c->name); + c->name = s; + } + else if(c->type == t_none) { + asprintf(&s, ".undef # %s", c->name); + free(c->name); + c->name = s; + } + } + } + + dict[i].del = 1; + + if(verbose && lf) fprintf(lf, "# deleting code: %d - %d\n", dict[i].def_idx, j); + c0->type = c1->type = c2->type = t_skip; + + changed = 1; + } + } + } + + return changed; +} + + +/* + * Find .undef. + */ +int optimize_code6(FILE *lf) +{ + unsigned i, j; + int changed = 0; + code_t *c0, *c1, *c2; + char *s; + + for(i = 0; i < code_size; i++) { + c0 = code + i; + c1 = code + (j = next_code(i)); + c2 = code + (j = next_code(j)); + if( + c0->type == t_int && c0->value.u == 0 && + c1->type == t_int && c1->value.u == 0 && + c2->type == t_prim && + c2->value.u == p_settype + ) { + c0->type = t_none; + c0->value.u = 0; + asprintf(&s, ".undef # %s", c0->name); + free(c0->name); + c0->name = s; + + if(verbose && lf) fprintf(lf, "# constant expression: .undef (at %d)\n", i); + if(verbose && lf) fprintf(lf, "# deleting code: %d - %d\n", i + 1, j); + c1->type = c2->type = t_skip; + + changed = 1; + } + } + + return changed; +} + + +/* + * Find constant boolean expr. + */ +int optimize_code7(FILE *lf) +{ + unsigned i, j; + int changed = 0; + code_t *c0, *c1, *c2; + char *s; + + for(i = 0; i < code_size; i++) { + c0 = code + i; + c1 = code + (j = next_code(i)); + c2 = code + (j = next_code(j)); + if( + c0->type == t_int && c0->value.u == 0 && + c1->type == t_int && c1->value.u == 0 && + c2->type == t_prim && + (c2->value.u == p_eq || c2->value.u == p_ne) + ) { + c0->type = t_bool; + c0->value.u = c0->value.u == c1->value.u ? 1 : 0; + if(c2->value.u == p_ne) c0->value.u ^= 1; + asprintf(&s, "%s # %s", c0->value.u ? "true" : "false", c0->name); + free(c0->name); + c0->name = s; + + if(verbose && lf) fprintf(lf, "# constant expression: %d:%d (at %d)\n", c0->type, c0->value.u, i); + if(verbose && lf) fprintf(lf, "# deleting code: %d - %d\n", i + 1, j); + c1->type = c2->type = t_skip; + + changed = 1; + } + } + + return changed; +} + + +void log_dict(FILE *lf) +{ + int i, j; + + if(!lf) return; + + fputc('\n', lf); + log_cline(lf); + fprintf(lf, "# dictionary: %d entries\n", dict_size); + log_cline(lf); + for(i = 0; i < dict_size; i++) { + fprintf(lf, "%5d%*s", i, 12 + (verbose ? 7 : 0), ""); + fprintf(lf, "%-6s ", type_name[dict[i].type & 15]); + if(dict[i].type == t_string) { + j = fprintf(lf, "\"%s\"", dict[i].value.p); + } + else { + j = fprintf(lf, "0x%x", dict[i].value.u); + } + if(j > 24) j = 24; + fprintf(lf, "%*s", 25 - j, ""); + fprintf(lf, "%s\n", dict[i].name ? dict[i].name : "\"\""); + } +} + + +void log_code(FILE *lf) +{ + int i, j, l, line = 0, incl_level = 0; + int ind = 0; + char *s; + + if(!lf) return; + + for(i = j = 0; i < code_size; i++) { + if(code[i].type == t_skip) j++; + } + + fputc('\n', lf); + log_cline(lf); + fprintf(lf, "# code: %d entries (%d - %d)\n", code_size - j, code_size, j); + log_cline(lf); + for(i = 0; i < code_size; i++) { + if(code[i].type == t_skip && !verbose) continue; + if((line != code[i].line || incl_level != code[i].incl_level) && code[i].line) { + line = code[i].line; + incl_level = code[i].incl_level; + fprintf(lf, "%5d", line); + if(incl_level) { + fprintf(lf, " %d ", incl_level); + } + else { + fprintf(lf, " "); + } + } + else { + fprintf(lf, "%9s", ""); + } + if(verbose) fprintf(lf, "%5d ", i); + if(code[i].size) { + fprintf(lf, "0x%04x ", code[i].ofs); + } + else { + fprintf(lf, "%*s", 8, ""); + } + fprintf(lf, "%-6s", type_name[code[i].type & 15]); + l = code[i].enc ? code[i].size : 0; + if(l > 8) l = 8; + for(j = 0; j < l; j++) { + fprintf(lf, " %02x", code[i].enc[j]); + } + if( + ( + code[i].type == t_ret || + (code[i].type == t_sec && !strcmp(code[i].name, "]")) + ) && + ind > 0 + ) ind -= 2; + fprintf(lf, "%*s", 3 * (8 - l) + 2 + ind, ""); + if(code[i].type == t_skip) fprintf(lf, "# "); + if( + code[i].type == t_code || + (code[i].type == t_sec && !strcmp(code[i].name, "[")) + ) ind += 2; + if(code[i].type == t_string) { + fprintf(lf, "\""); + s = code[i].value.p; + while(*s) { + if(*s >= 0 && *s < 0x20) { + if(*s == '\n') { + fprintf(lf, "\\n"); + } + else if(*s == '\t') { + fprintf(lf, "\\t"); + } + else { + fprintf(lf, "\\x%02x", (unsigned char) *s); + } + } + else { + fprintf(lf, "%c", *s); + } + s++; + } + fprintf(lf, "\""); + } + else { + fprintf(lf, + "%s%s", + code[i].type == t_dict_idx ? "/" : "", + code[i].name ? code[i].name : "" + ); + } + + // while we're here, just do a consistency check + if( + code[i].type == t_sec && + ( + !code[i].name || + strcmp(code[i].name, dict[code[i].value.u].name) + ) + ) { + fprintf(stderr, "Internal oops %d: broken dictionary\n", __LINE__); + exit(19); + } + + if(code[i].enc && code[i].size > 8) { + for(j = 8; j < code[i].size; j++) { + if(j & 7) { + fprintf(lf, " "); + } + else { + fprintf(lf, "\n%*s", 24 + (verbose ? 7 : 0), ""); + } + fprintf(lf, "%02x", code[i].enc[j]); + } + } + fprintf(lf, "\n"); + } +} + + +void log_cline(FILE *lf) +{ + int i = 78; + + fputc('#', lf); + while(i--) fputc('-', lf); + fputc('\n', lf); +} + + +char *add_to_line(char *s) +{ + static char buf[10240] = {}; + static int ind = 0; + static int first = 1; + + if(!s) { + if(first) return ""; + return buf; + } + + if(strlen(buf) + strlen(s) >= sizeof buf - 1) { + fprintf(stderr, "Oops, buffer overflow %d\n", __LINE__); + exit(5); + } + + if(!strcmp(s, "{")) ind += 2; + if(!strcmp(s, "}")) ind -= 2; + if(ind < 0) ind = 0; + + if(!*s) { + sprintf(buf, "%*s", ind, ""); + first = 1; + return buf; + } + + if(first) { + if(!strcmp(s, "}")) { + sprintf(buf, "%*s", ind, ""); + } + } + else { + strcat(buf, " "); + } + + strcat(buf, s); + + first = 0; + + return buf; +} + +void decompile(unsigned char *data, unsigned size) +{ + int i, j, idx = 0; + unsigned u, val, uc; + unsigned inst_size; + dict_t *d; + unsigned type; + char *s, buf[1024]; + unsigned char *p; + + // setup initial vocabulary + for(i = 0; i < sizeof prim_names / sizeof *prim_names; i++) { + d = new_dict(); + d->type = prim_names[i].type; + d->value.u = prim_names[i].value; + d->name = prim_names[i].name; + } + + for(i = 0; i < size; i += inst_size, idx++) { + u = (data[i] >> 4) & 7; + val = 0; + if(u >= 1) val = data[i + 1]; + if(u >= 2) val += data[i + 2] << 8; + if(u >= 3) val += data[i + 3] << 16; + if(u >= 4) val += data[i + 4] << 24; + inst_size = 1 + u; + if((data[i] >> 4) & 8) { + inst_size += val; + } + + if(i + inst_size > size) { + printf("Oops: bounds exceeded: %u > %u\n", i + inst_size, size); + return; + } + + if(verbose >= 1) { + printf("%% %04x:", i); + for(j = 0; j < inst_size; j++) { + printf(" %02x", data[i + j]); + } + printf("\n"); + } + + switch((type = data[i] & 0x0f)) { + case t_code: + s = add_to_line("{"); + printf("%s\n", s); + add_to_line(""); + break; + + case t_ret: + s = add_to_line(NULL); + if(*s) printf("%s\n", s); + add_to_line(""); + add_to_line("}"); + break; + + case t_end: + uc = *add_to_line(NULL); + s = add_to_line("end"); + if(uc) { + printf("%s\n", s); + } + else { + printf("%s\n\n", s); + } + add_to_line(""); + break; + + case t_int: + // expand sign bit + switch(u) { + case 1: + if(val & 0x80) val |= ~0xff; + break; + case 2: + if(val & 0x8000) val |= ~0xffff; + break; + case 3: + if(val & 0x800000) val |= ~0xffffff; + break; + } + + case t_unsigned: + sprintf(buf, "%d", val); + add_to_line(buf); + break; + + case t_string: + buf[0] = '"'; + for(j = 1, p = data + i + u + 1; *p && j < sizeof buf - 10; p++) { + if(*p == '\n') { + buf[j++] = '\\'; + buf[j++] = 'n'; + } + else if(*p < 0x20 || *p >= 0x7f) { + buf[j++] = '\\'; + buf[j++] = 'x'; + uc = *p >> 4; + uc += uc > 9 ? 'a' - 10 : '0'; + buf[j++] = uc; + uc = *p & 0xf; + uc += uc > 9 ? 'a' - 10 : '0'; + buf[j++] = uc; + } + else { + buf[j++] = *p; + } + } + buf[j++] = '"'; + buf[j] = 0; + s = add_to_line(buf); + break; + + case t_sec: + if(val < dict_size && dict[val].name) { + sprintf(buf, "%s", dict[val].name); + } + else { + sprintf(buf, "name_%d", val); + } + s = add_to_line(buf); + printf("%s\n", s); + add_to_line(""); + break; + + case t_dict_idx: + if(val < dict_size && dict[val].name) { + sprintf(buf, "/%s", dict[val].name); + } + else { + sprintf(buf, "/name_%d", val); + } + add_to_line(buf); + break; + + default: + fprintf(stderr, "Oops %d: type %d not allowed\n", __LINE__, type); + exit(8); + } + } +} + + diff --git a/modplay.inc b/modplay.inc new file mode 100644 index 0000000..4a5e253 --- /dev/null +++ b/modplay.inc @@ -0,0 +1,1141 @@ +; MOD player (c) 2002 mls +; +; generates samples for 11000 HZ +; bpm always 125 + + +%if 0 + call init + sti + call loadmod + sti + call play + sti + call playmod + sti + call playsamp + sti + call setvol + sti + call getvol + sti + call getstate + sti + call stop + sti +%endif + +; pl_loadmod - configure a mod player +; ds:si start of player +; es:di start of mod +; si,di must be reasonable small ;) +pl_loadmod: + pushad + push si + add si, pl_state + xor ax, ax + mov cx, pl_sizeof - pl_state +sm1: mov [si], al + inc si + loop sm1 + pop si + mov [si + pl_seg], es + mov dx, si + mov cx, 4 + push si + add si, pl_channs +sm10: mov [si + ch_player], dx + add si, ch_sizeof + loop sm10 + pop si + mov dx, 32 + mov eax, [es:di + 0x438] + cmp eax, 'CHN4' + jz sm2 + cmp eax, 'M.K.' + jz sm2 + cmp eax, 'M&K!' + jz sm2 + cmp eax, 'FLT4' + jz sm2 + mov dl, 16 +sm2: add di, 20 + 22 + mov [si + pl_sampinfo], di + sub di, 22 + 30 + mov cx, dx + imul cx, 30 + add di, cx + mov al, [es:di] + mov [si + pl_songlen], al + inc di + inc di + mov [si + pl_song], di + xor bx, bx + mov cx, 128 +sm5: mov al, [es:di] + inc di + cmp bl, al + jge sm4 + mov bl, al +sm4: loop sm5 + inc bl + cmp dl, 32 + jnz sm6 + add di, 4 +sm6: mov [si + pl_patterns], di + mov cx, bx +sm7: add di, 64 * 16 + loop sm7 + mov [si + pl_speed], byte 6 + mov [si + pl_effpos], byte 6 + mov [si + pl_loaded], byte 1 + mov cx, dx + dec cx + mov dx, es + mov bx, di + mov di, [si + pl_sampinfo] + add si, pl_sampd + 2 +sm9: push bx + shr bx, 4 + add dx, bx + pop bx + and bx, 0x000f + mov [si], bx + mov [si + 2 * 32], dx + mov ax, [es:di] + xchg al, ah + add bx, ax + adc dx, 0 + add bx, ax + adc dx, 0 + add si, 2 + add di, 30 + loop sm9 + popad + ret + +; pl_play - play modfile +; ds:si start of player +; es:di buffer to add samples +pl_play: + pushad + push es + push di + + call fixvol + + mov ax, [si + pl_state] + or ax, ax + jz p3 + dec ax + jnz near p1 + + ; run effects + push si + add si, pl_channs + mov cx, 4 +p31: mov ax, [si + ch_effect] + or ax, ax + jz p30 + call doeff + call norm +p30: add si, ch_sizeof + loop p31 + pop si + + inc word [si + pl_effpos] + mov ax, [si + pl_effpos] + cmp ax, [si + pl_speed] + jb near p1 + + ; advance note + xor ax, ax + mov [si + pl_effpos], ax + mov bx, [si + pl_nextsongnum] + mov [si + pl_songnum], bx + mov cx, [si + pl_songlen] + cmp bx, cx + jb p2 +p3: mov [si + pl_state], ax + pop di + pop es + popad + ret +p2: mov dx, [si + pl_nextnotenum] + mov [si + pl_notenum], dx + cmp dx, 64 + jnb p3 + inc dx + cmp dl, 64 + jb p4 + xor dl, dl + inc bx + cmp bx, cx + jb p5 + xor bx, bx +p5: mov [si + pl_nextsongnum], bx +p4: mov [si + pl_nextnotenum], dx + + ; interpret events for each channel + mov bx, [si + pl_songnum] + mov es, [si + pl_seg] + add bx, [si + pl_song] + mov bl, [es:bx] + cmp bl, 0x80 + jb p11 + xor bl, bl +p11: xor bh, bh + shl bx, 6 + add bx, [si + pl_notenum] + shl bx, 4 + add bx, [si + pl_patterns] + + mov di, [si + pl_sampinfo] + push si + add si, pl_channs + + mov cx, 4 +p18: mov ah, [es:bx] + and ah, 0x10 + mov al, [es:bx + 2] + shr al, 4 + or al, ah + jz p16 + call setsamp +p16: mov ah, [es:bx] + and ah, 0x0f; + mov al, [es:bx + 1] + or ax, ax + jz p17 + mov [si + ch_pitchgoal], ax + mov dl, [es:bx + 2] + inc dl + or dl, 0xf2 + cmp dl, 0xf6 + jz p17 + mov [si + ch_pitch], ax + xor ax, ax + mov [si + ch_pointer], ax + mov [si + ch_pointer8], ax + mov ax, [si + ch_send] + mov [si + ch_end], ax +p17: xor ax, ax + mov [si + ch_effect], ax + mov dl, [es:bx + 3] + mov al, [es:bx + 2] + and al, 0x0f + or dl, al + jz p29 + push di + mov di, [si + ch_player] + mov dl, [es:bx + 3] + xor dh, dh + call effects + pop di +p29: call norm + add si, ch_sizeof + add bx, 4 + dec cx + jnz near p18 + pop si + + ; prepare playing of each channel +p1: push si + add si, pl_channs + mov cx, 4 +p10: mov ax, [si + ch_end] + or ax, ax + jnz p6 +p8: mov [si + ch_start], ax + mov [si + ch_startseg], ax + jmp p7 +p6: mov ax, [si + ch_pitch] + or ax, ax + jz p8 + mov bx, [si + ch_samp] + or bx, bx + jz p8 + mov dx, si + pop si + push si + add bx, bx + add si, bx + mov bx, [si + pl_sampd] + mov si, [si + pl_sampdseg] + xchg si, dx + mov [si + ch_start], bx + mov [si + ch_startseg], dx + mov dx, [si + ch_finetune] + add dx, dx + jz p9 + mov dx, [cs: fttab] + mul dx + shl ax, 1 + mov ax, dx + adc ax, ax +p9: mov bx, ax + mov ax, 57213 + xor dx, dx + div bx + mov [si + ch_step], ah + mov [si + ch_step8], al +p7: add si, ch_sizeof + loop p10 + pop si + + ; now generate 320 samples for each channel + pop di + pop es + add si, pl_channs + mov ax, 320 +p21: push ax + mov cx, 4 +p20: mov bx, [si + ch_startseg] + or bx, bx + jz near p22 + push es + mov es, bx + mov bx, [si + ch_start] + mov ax, [si + ch_pointer] + add bx, ax + movsx dx, [es:bx] + shl dx, 2 + inc ax + cmp ax, [si + ch_end] + jnb p23 + inc bx + movsx ax, [es:bx] + push cx + mov cx, [si + ch_pointer8] + or cx, cx + jz p24 + sar dx, 2 + imul ax, cx + neg cl + imul dx, cx + add dx, ax + sar dx, 6 +p24: pop cx +p23: pop es + imul dx, [si + ch_volume] + sar dx, 2 + push si + mov si, [si + ch_player] + movzx eax, word [si + pl_volume] + pop si + movsx edx, dx + imul edx + sar eax, 16 + add ax, word [es:di] + jno p40 + mov ax, 32767 + js p40 + inc ax +p40: mov [es:di], ax + mov bx, [si + ch_pointer8] + mov ax, [si + ch_pointer] + add bl, [si + ch_step8] + adc ax, [si + ch_step] + mov [si + ch_pointer8], bl + cmp ax, [si + ch_end] + jb p25 + mov ax, [si + ch_roff] + mov bx, [si + ch_rend] + mov [si + ch_end], bx + or bx, bx + jnz p25 + mov [si + ch_startseg], bx +p25: mov [si + ch_pointer], ax +p22: add si, ch_sizeof + dec cx + jnz near p20 + add di, 2 + sub si, ch_sizeof * 4 + pop ax + dec ax + jnz near p21 + sub si, pl_channs + mov ax, [si + pl_state] + dec ax + jz p50 + add si, pl_channs + mov cx, 4 +p51: mov ax, [si + ch_startseg] + or ax, ax + jnz p50 + add si, ch_sizeof + loop p51 + sub si, ch_sizeof * 4 + pl_channs + mov [si + pl_state], ax +p50: popad + ret + +fttab: dw 32768, 32532, 32298, 32066 + dw 31835, 31606, 31378, 31153 + dw 34716, 34466, 34219, 33972 + dw 33728, 33485, 33244, 33005 + +; norm - normalize channel values +; ds:si start of chanel +norm: push ax + mov ax, [si + ch_volume] + or ax, ax + jns n1 + xor ax, ax +n1: cmp ax, 64 + jb n2 + mov ax, 64 +n2: mov [si + ch_volume], ax + mov ax, [si + ch_pitch] + or ax, ax + jnb n3 + xor ax, ax + mov [si + ch_pitch], ax +n3: pop ax + ret + +arptab: dw 0, 61858, 58386, 55109 + dw 52016, 49097, 46341, 43740 + dw 41285, 38968, 36781, 34716 + dw 32768, 30929, 29193, 27554 + +; effects - interpret effect +; ax effect +; dx arg +; ds:di start of player +; ds:si start of chanel +; +; trashes ax, dx +effects: + or al, al + jnz e1 + mov [si + ch_arpindex], ax + mov ax, [si + ch_pitch] + mov [si + ch_arp], ax + push dx + push ax + shr dl, 4 + jz e1b + push bx + mov bx, dx + add bl, bl + mov dx, [cs: arptab + bx] + pop bx + mul dx + mov ax, dx +e1b: mov [si + ch_arp + 2], ax + pop ax + pop dx + and dl, 0x0f + jz e1a + push bx + mov bx, dx + add bl, bl + mov dx, [cs: arptab + bx] + pop bx + mul dx + mov ax, dx +e1a: mov [si + ch_arp + 4], ax + mov [si + ch_effect], byte EFF_ARP + ret +e1: cmp al, 1 + jnz e2 + neg dx + jmp e3 +e2: cmp al, 2 + jnz e4 +e3: or dl, dl + jz e5 + mov [si + ch_slide], dx +e5: mov [si + ch_effect], byte EFF_SLIDE + ret +e4: cmp al, 3 + jnz e6 + or dl, dl + jz e7 + mov [si + ch_pitchrate], dx +e7: mov [si + ch_effect], byte EFF_PORTA + ret +e6: cmp al, 4 + jnz e8 + mov ax, dx + shr ax, 4 + jz e9 + mov [si + ch_vibrate], ax +e9: and dl, 0x0f + jz e10 + mov [si + ch_vibdepth], dx +e10: mov [si + ch_effect], byte EFF_VIBRA + ret +e8: cmp al, 5 + jnz e11 + mov [si + ch_effect], byte EFF_PORTASLIDE + jmp e12 +e11: cmp al, 6 + jnz e13 + mov [si + ch_effect], byte EFF_VIBRASLIDE + jmp e12 +e13: cmp al, 9 + jnz e14 + mov ax, [si + ch_samp] + or al, al + jz e15 + xor ax, ax + mov [si + ch_pointer8], ax + mov ax, [si + ch_send] + mov [si + ch_end], ax + shl dx, 8 + cmp dx, ax + jb e16 + sub dx, ax + mov ax, [si + ch_rend] + mov [si + ch_end], ax + sub ax, [si + ch_roff] + jz e17 +e18: cmp dx, ax + jb e17 + sub dx, ax + jmp e18 +e17: add dx, [si + ch_roff] +e16: mov [si + ch_pointer], dx +e15: ret +e14: cmp al, 10 + jnz e19 + mov [si + ch_effect], byte EFF_SLIDEVOL +e12: mov ax, dx + and dl, 0x0f + jz e20 + neg dx + jmp e21 +e20: mov dx, ax + shr dl, 4 +e21: mov [si + ch_volumerate], dx + ret +e19: cmp al, 11 + jnz e22 + mov [di + pl_nextsongnum], dx + xor dx, dx + mov [di + pl_nextnotenum], dx + ret +e22: cmp al, 12 + jnz e23 + mov [si + ch_volume], dx + ret +e23: cmp al, 13 + jnz e24 + mov ax, dx + shr al, 4 + imul ax, 10 + and dx, 0x0f + add dx, ax + mov [di + pl_nextnotenum], dx + mov dx, [di + pl_songnum] + inc dx + mov ax, [di + pl_songlen] + cmp dx, ax + jb e25 + xor dx, dx +e25: mov [di + pl_nextsongnum], dx + ret +e24: cmp al, 15 + jnz e27 + cmp dl, 32 + jnb e26 + mov [di + pl_speed], dx +e26: ret +e27: cmp al, 14 + jnz e26 + mov al, dl + shr al, 4 + and dl, 0x0f + cmp al, 1 + jnz e28 +e30: add [si + ch_pitch], dx + ret +e28: cmp al, 2 + jnz e29 + neg dx + jmp e30 +e29: cmp al, 5 + jnz e31 + mov [si + ch_finetune], dx + ret +e31: cmp al, 6 + jnz e32 + or dl, dl + jnz e33 + mov dx, [di + pl_notenum] + mov [di + pl_loop_notenum], dx + ret +e33: mov ax, [di + pl_loop_counter] + or ax, ax + jnz e34 + mov ax, dx + inc ax +e34: dec ax + mov [di + pl_loop_counter], ax + jz e35 + mov dx, [di + pl_loop_notenum] + mov [di + pl_nextnotenum], dx +e35: ret +e32: cmp al, 9 + jnz e36 + mov [si + ch_retrig], dx + mov [si + ch_current], dx + mov [si + ch_effect], byte EFF_RETRIG + ret +e36: cmp al, 10 + jnz e37 +e39: add [si + ch_volume], dx + ret +e37: cmp al, 11 + jnz e38 + neg dx + jmp e39 +e38: cmp al, 12 + jnz e40 + mov [si + ch_retrig], dx + mov [si + ch_effect], byte EFF_CUT + ret +e40: cmp al, 13 + jnz e41 + mov [si + ch_current], dx + mov dx, [si + ch_samp] + mov [si + ch_latesamp], dx + xor dx, dx + mov [si + ch_samp], dx + mov [si + ch_effect], byte EFF_LATESTART + ret +e41: cmp al, 14 + jnz e42 + inc dx + imul dx, [di + pl_speed] + sub [di + pl_effpos], dx +e42: ret + +vibtab: dw 0, 50, 100, 149, 196, 241, 284, 325 + dw 362, 396, 426, 452, 473, 490, 502, 510 + dw 512, 510, 502, 490, 473, 452, 426, 396 + dw 362, 325, 284, 241, 196, 149, 100, 50 + dw 0, -49, -99,-148,-195,-240,-283,-324 + dw -361,-395,-425,-451,-472,-489,-501,-509 + dw -511,-509,-501,-489,-472,-451,-425,-395 + dw -361,-324,-283,-240, -195,-148,-99, -49 + +; doeff - apply channel effect +; ax effect +; ds:si start of chanel +; +; trashes ax, bx +doeff: + bt ax, 3 + jnc d1 + mov bx, [si + ch_volumerate] + add [si + ch_volume], bx + sub al, 8 +d1: cmp al, EFF_ARP + jnz d2 + mov bx, [si + ch_arpindex] + inc bl + cmp bl, 3 + jb d3 + xor bl, bl +d3: mov [si + ch_arpindex], bl + add bl, bl + mov ax, [si + ch_arp + bx] + mov [si + ch_pitch], ax + ret +d2: cmp al, EFF_SLIDE + jnz d4 + mov ax, [si + ch_slide] + add [si + ch_pitch], ax + ret +d4: cmp al, EFF_PORTA + jnz d5 + mov ax, [si + ch_pitch] + mov bx, [si + ch_pitchgoal] + cmp ax, bx + jnb d6 + add ax, [si + ch_pitchrate] + cmp ax, bx + jb d7 +d8: mov ax, bx +d7: mov [si + ch_pitch], ax + ret +d6: sub ax, [si + ch_pitchrate] + cmp ax, bx + jb d8 + jmp d7 +d5: cmp al, EFF_VIBRA + jnz d9 + mov bx, [si + ch_viboffset] + add bx, [si + ch_vibrate] + and bx, 0x3f + mov [si + ch_viboffset], bx + add bx, bx + mov ax, [cs: vibtab + bx] + imul ax, [si + ch_vibdepth] + sar ax, 8 + add ax, [si + ch_pitchgoal] + mov [si + ch_pitch], ax +d12: ret +d9: cmp al, EFF_RETRIG + jnz d10 + dec word [si + ch_current] + jz d11 + jns d12 +d11: mov ax, [si + ch_retrig] + mov [si + ch_current], ax + mov ax, [si + ch_send] + mov [si + ch_end], ax + xor ax, ax + mov [si + ch_pointer], ax + mov [si + ch_pointer8], ax + ret +d10: cmp al, EFF_CUT + jnz d13 + mov ax, [si + ch_retrig] + jz d14 + dec word [si + ch_retrig] + jnz d14 + xor ax, ax + mov [si + ch_volume], ax +d14: ret +d13: cmp al, EFF_LATESTART + jnz d14 + dec word [si + ch_current] + jz d15 + jns d14 +d15: call d11 + mov [si + ch_current], ax + mov [si + ch_effect], ax + mov ax, [si + ch_latesamp] + mov [si + ch_samp], ax + ret + +; fixvol - fixup volume +; ds:si start of volblock +fixvol: + push ax + push bx + mov ax, [si + vo_volume] + mov bx, [si + vo_volumegoal] + cmp ax, bx + jz vo3 + jnb vo1 + add ax, [si + vo_volumerate] + jc vohit + cmp ax, bx + jb vo2 +vohit: mov ax, bx +vo2: mov [si + vo_volume], ax +vo3: pop bx + pop ax + ret +vo1: sub ax, [si + vo_volumerate] + jc vohit + cmp ax, bx + jb vohit + jmp vo2 + +; vo_setvol - set volume +; ds:si start of volblock +; ax goal +; bx rate 0=immediate 50=one sec +vo_setvol: + mov [si + vo_volumegoal], ax + or bx, bx + jnz sv1 + mov [si + vo_volume], ax + mov [si + vo_volumerate], bx + ret +sv1: push ax + xor ax, ax + not ax + push dx + div bx + pop dx + mov [si + vo_volumerate], ax + pop ax + ret + +; getvol - get volume +; ds:si start of volblock +vo_getvol: + mov ax, [si + vo_volume] + ret + +; pl_playmod - play a modfile +; ds:si start of player +; ax start of song +pl_playmod: + cmp [si + pl_loaded], byte 1 + jz pm0 + ret +pm0: xor bx, bx + mov [si + pl_state], bx + mov [si + pl_speed], byte 6 + mov [si + pl_effpos], byte 6 + mov [si + pl_nextsongnum], ax + mov [si + pl_nextnotenum], bx + call clearchans + inc bx + mov [si + pl_state], bx + ret + +; pl_playsamp - play a sample +; ds:si start of player +; ax channel number +; bx sample number +; cx pitch +pl_playsamp: + cmp [si + pl_loaded], byte 1 + jz ps0 + ret +ps0: push ax + mov ax, [si + pl_state] + dec ax + dec ax + jz ps1 + call clearchans +ps1: pop ax + pusha + push es + mov es, [si + pl_seg] + mov di, [si + pl_sampinfo] + add si, pl_channs + imul ax, ch_sizeof + add si, ax + xor ax, ax + mov [si + ch_startseg], ax + mov [si + ch_effect], ax + mov [si + ch_pointer], ax + mov [si + ch_pointer8], ax + mov [si + ch_pitch], cx + mov ax, bx + or ax, ax + jz ps2 + call setsamp +ps2: pop es + mov ax, [si + ch_send] + mov [si + ch_end], ax + popa + mov [si + pl_state], byte 2 + ret + +; pl_getstate - get state of player +; ds:si start of player +pl_getstate: + mov ax, [si + pl_state] + ret + +; pl_getstate - get state of player +; ds:si start of player +pl_stop: + mov [si + pl_state], byte 0 + ret + +; clearchans - stop all channels +; si start of player +clearchans: + push si + push cx + push ax + xor ax, ax + add si, pl_channs + mov cx, 4 +cc1: mov [si + ch_startseg], ax + mov [si + ch_effect], ax + add si, ch_sizeof + loop cc1 + pop ax + pop cx + pop si + ret + +; setsamp - start a sample +; si start of channel +; es:di start of sampinfo +; ax sample number +; +; trashes ax, dx +setsamp: + xor ah, ah + mov [si + ch_samp], ax + dec ax + imul ax, 30 + push bx + mov bx, ax + mov ax, [es:di + bx] + xchg ah, al + add ax, ax + mov [si + ch_send], ax + mov ax, [es:di + bx + 4] + xchg ah, al + add ax, ax + mov [si + ch_roff], ax + mov dx, [es:di + bx + 6] + xchg dh, dl + add dx, dx + mov [si + ch_rend], dx + add ax, dx + mov dx, [si + ch_send] + dec ax + dec ax + cmp ax, dx + jna ss13 + shr word [si + ch_roff], 1 +ss13: mov ax, [si + ch_roff] + add ax, [si + ch_rend] + cmp dx, [si + ch_roff] + jnb ss14 +ss16 xor ax, ax + mov [si + ch_roff], ax +ss14: cmp dx, ax + jnb ss15 + mov ax, dx +ss15: mov [si + ch_rend], ax + dec ax + dec ax + jz ss16 + mov al, [es:di + bx + 2] + mov [si + ch_finetune], al + mov al, [es:di + bx + 3] + mov [si + ch_volume], al + pop bx + ret + +; the big picture: four mod players + +; init - initiaize everything +; ds:si start of area +init: + pushad + push si + xor ax, ax + mov cx, ar_sizeof +ii1: mov [si], al + inc si + loop ii1 + pop si + not ax + xor bx, bx + push si + add si, ar_players + mov cx, 4 +ii2: call vo_setvol + add si, pl_sizeof + loop ii2 + pop si + add si, ar_volume + mov ax, 32767 + call vo_setvol + popad + ret + +; setpl - get player offset +; ax player no. +setpl: + add si, ar_players + imul ax, pl_sizeof + add si, ax + ret + +; loadmod - load a mod into one of the players +; ds:si start of area +; es:di start of mod +; ax player no. +loadmod: + push si + call setpl + call pl_loadmod + pop si + ret + +; playmod - play a modfile +; ds:si start of area +; ax player no. +; bx start of song +playmod: + push si + call setpl + mov ax, bx + call pl_playmod + pop si + ret + +; playsamp - play a sample +; ds:si start of area +; ax player no. +; bx channel number +; cx sample number +; dx pitch +playsamp: + push si + call setpl + mov ax, bx + mov bx, cx + mov cx, dx + call pl_playsamp + pop si + ret + +; getstate - get state of player +; ds:si start of area +; ax player no. +getstate: + push si + call setpl + call pl_getstate + pop si + ret + +; stop - stop a player +; ds:si start of area +; ax player no. +stop: + push si + call setpl + call pl_stop + pop si + ret + +pctab: + db 64, 64, 64, 64, 64, 64, 64, 64 + db 64, 64, 63, 63, 63, 63, 63, 63 + db 63, 63, 63, 63, 63, 63, 62, 62 + db 62, 62, 62, 62, 62, 62, 62, 62 + db 61, 61, 61, 61, 61, 61, 61, 61 + db 61, 60, 60, 60, 60, 60, 60, 60 + db 60, 60, 60, 59, 59, 59, 59, 59 + db 59, 59, 59, 59, 59, 58, 58, 58 + db 58, 58, 58, 58, 58, 58, 58, 57 + db 57, 57, 57, 57, 57, 57, 57, 57 + db 57, 56, 56, 56, 56, 56, 56, 56 + db 56, 55, 55, 55, 55, 55, 54, 54 + db 54, 54, 53, 53, 53, 53, 52, 52 + db 52, 51, 51, 50, 50, 49, 49, 48 + db 48, 47, 46, 45, 44, 43, 42, 41 + db 40, 39, 38, 37, 36, 35, 34, 33 + db 32, 31, 30, 29, 28, 27, 26, 25 + db 24, 23, 22, 21, 20, 19, 18, 17 + db 17, 16, 16, 15, 15, 14, 14, 13 + db 13, 13, 12, 12, 12, 12, 11, 11 + db 11, 11, 10, 10, 10, 10, 10, 9 + db 9, 9, 9, 9, 9, 9, 9, 9 + db 8, 8, 8, 8, 8, 8, 8, 8 + db 8, 8, 8, 8, 7, 7, 7, 7 + db 7, 7, 7, 6, 6, 6, 6, 6 + db 6, 6, 6, 6, 6, 6, 5, 5 + db 5, 5, 5, 5, 5, 5, 5, 5 + db 4, 4, 4, 4, 4, 4, 4, 4 + db 4, 4, 3, 3, 3, 3, 3, 3 + db 3, 3, 3, 3, 2, 2, 2, 2 + db 2, 2, 2, 2, 2, 1, 1, 1 + db 1, 1, 1, 1, 1, 1, 1, 1 + +; play - generate samples +; ds:si start of area +play: + pushad + push es + push si + xor ax, ax + mov cx, ar_volume +ap1: mov [si], al + inc si + loop ap1 + call fixvol + pop si + push si + add si, ar_ssamps + mov di, si + push ds + pop es + mov cx, ar_sizeof - ar_ssamps +ap2: mov [si], al + inc si + loop ap2 + pop si + push si + mov cx, 4 + xor bx, bx + add si, ar_players +ap4: mov ax, [si + pl_state] + or ax, ax + jz ap3 + call pl_play + mov ax, [si + pl_volume] + or ax, ax + jz ap3 + mov bl, 1 +ap3: add si, pl_sizeof + loop ap4 + pop si + movzx eax, word [si + ar_volume] + or ax, ax + jz ap5 + mov [si + ar_hassamp], bl + mov cx, 320 + xor bx, bx +ap6: movsx edx, word [si + bx + ar_ssamps] + imul edx, eax + + sar edx, 16-2 + + cmp edx,32767 + jl ap7 + mov edx,32767 +ap7: + cmp edx,-32768 + jg ap8 + mov edx,-32768 + +ap8: + add dh, 128 + push bx + xor bx, bx + mov bl, dh + mov dl, [cs: pctab + bx] + pop bx + mov [si + ar_samps], dl + inc si + inc bx + loop ap6 +ap5: pop es + popad + ret + +; setvol - set volume +; ds:si start of area +; ax player no. +; bx goal +; cx rate 0=immediate 50=one sec +setvol: + push si + call setplvl + mov ax, bx + mov bx, cx + call vo_setvol + pop si + ret + +; getvol - get volume +; ds:si start of area +; ax player no. +getvol: + push si + call setplvl + call vo_getvol + pop si + ret + +; setplvl - get volume offset +; ax player no. +setplvl: + or ax, ax + js av1 + jmp setpl +av1: add si, ar_volume + ret + diff --git a/modplay_defines.inc b/modplay_defines.inc new file mode 100644 index 0000000..cb440b9 --- /dev/null +++ b/modplay_defines.inc @@ -0,0 +1,92 @@ +; MOD player (c) 2002 mls +; +; generates samples for 11000 HZ +; bpm always 125 + +STATE_OFF equ 0 +STATE_PLAY equ 1 +STATE_SAMPLE equ 2 + +; struct volume +vo_volume equ 0 +vo_volumegoal equ vo_volume + 2 +vo_volumerate equ vo_volumegoal + 2 +vo_sizeof equ vo_volumerate + 2 + +; struct channel +ch_samp equ 0 +ch_startseg equ ch_samp + 2 +ch_pitch equ ch_startseg + 2 +ch_finetune equ ch_pitch + 2 +ch_volume equ ch_finetune + 2 + +ch_start equ ch_volume + 2 +ch_pointer equ ch_start + 2 +ch_pointer8 equ ch_pointer + 2 +ch_end equ ch_pointer8 + 2 +ch_send equ ch_end + 2 +ch_roff equ ch_send + 2 +ch_rend equ ch_roff + 2 +ch_step equ ch_rend + 2 +ch_step8 equ ch_step + 2 + +ch_slide equ ch_step8 + 2 +ch_vibrate equ ch_slide + 2 +ch_viboffset equ ch_vibrate + 2 +ch_vibdepth equ ch_viboffset + 2 +ch_pitchgoal equ ch_vibdepth + 2 +ch_pitchrate equ ch_pitchgoal + 2 +ch_volumerate equ ch_pitchrate + 2 +ch_arpindex equ ch_volumerate + 2 +ch_arp equ ch_arpindex + 2 +ch_current equ ch_arp + 3 * 2 +ch_retrig equ ch_current + 2 +ch_latesamp equ ch_retrig + 2 +ch_effect equ ch_latesamp + 2 +ch_player equ ch_effect + 2 +ch_sizeof equ ch_player + 2 + +; struct player +pl_volume equ 0 +pl_state equ pl_volume + vo_sizeof +pl_songlen equ pl_state + 2 +pl_speed equ pl_songlen + 2 +pl_effpos equ pl_speed + 2 +pl_nextsongnum equ pl_effpos + 2 +pl_nextnotenum equ pl_nextsongnum + 2 +pl_songnum equ pl_nextnotenum + 2 +pl_notenum equ pl_songnum + 2 +pl_loop_notenum equ pl_notenum + 2 +pl_loop_counter equ pl_loop_notenum + 2 +pl_seg equ pl_loop_counter + 2 +pl_song equ pl_seg + 2 +pl_patterns equ pl_song + 2 +pl_sampinfo equ pl_patterns + 2 +pl_sampd equ pl_sampinfo + 2 +pl_sampdseg equ pl_sampd + 2 * 32 +pl_channs equ pl_sampdseg + 2 * 32 +pl_loaded equ pl_channs + 4 * ch_sizeof +pl_sizeof equ pl_loaded + 2 + +EFF_ARP equ 1 +EFF_SLIDE equ 2 +EFF_PORTA equ 3 +EFF_VIBRA equ 4 +EFF_RETRIG equ 5 +EFF_CUT equ 6 +EFF_LATESTART equ 7 +EFF_SLIDEVOL equ 8 +EFF_PORTASLIDE equ 8 + 3 +EFF_VIBRASLIDE equ 8 + 4 + + ; _must_ be 320 +num_samples equ 320 + +; struct area +ar_hassamp equ 0 +ar_samps equ ar_hassamp + 1 +ar_volume equ ar_samps + num_samples + 1 +ar_players equ ar_volume + vo_sizeof +ar_ssamps equ ar_players + pl_sizeof * 4 +ar_sizeof equ ar_ssamps + num_samples * 2 + diff --git a/themes/SuSE/16x16.font b/themes/SuSE/16x16.font Binary files differnew file mode 100644 index 0000000..5bd9fd8 --- /dev/null +++ b/themes/SuSE/16x16.font diff --git a/themes/SuSE/Makefile b/themes/SuSE/Makefile new file mode 100644 index 0000000..9d02750 --- /dev/null +++ b/themes/SuSE/Makefile @@ -0,0 +1,54 @@ +HELP2TXT = $(BINDIR)help2txt +MKBOOTMSG = $(BINDIR)mkbootmsg +BFLAGS = -O -v -L ../.. +INCLUDES = $(wildcard *.inc) +HELPBOOT = help-boot.en.txt help-boot.cs.txt help-boot.sk.txt +HELPINST = help-install.en.txt +TRANSL = texts.en texts.cs texts.de texts.sk + +FILES_INST = init $(TRANSL) help.en \ + 16x16.font kroete.data background.pcx splash.pcx +FILES_BOOT = init $(TRANSL) help.en help.cs help.sk 16x16.font background.pcx + +%.txt: %.html + $(HELP2TXT) $< >$@ + +.PHONY: all themes clean po + +all: themes + +po: + make -C po + +themes: boot install + +boot install: po + +boot: boot.config $(INCLUDES) $(HELPBOOT) + @mkdir -p $@ + @cp -a po/texts.* . + $(MKBOOTMSG) $(BFLAGS) -l $@/log -c $< init + @cp help-$@.en.txt help.en + @cp help-$@.cs.txt help.cs + @cp help-$@.sk.txt help.sk + @echo $(FILES_BOOT) | sed -e 's/ /\n/g' | cpio --quiet -o >$@/message + @mv init help.en help.cs help.sk $@ + @mv texts.* $@ + +install: install.config $(INCLUDES) $(HELPINST) + @mkdir -p $@ + @cp -a po/texts.* . + $(MKBOOTMSG) $(BFLAGS) -l $@/log -c $< init +# @echo de >lang + @cp help-$@.en.txt help.en +# @cp help-$@.de.txt help.de + @echo $(FILES_INST) | sed -e 's/ /\n/g' | cpio --quiet -o >$@/bootlogo + @mv init help.en $@ + @mv texts.* $@ +# @rm -f lang + +clean: + make -C po clean + rm -f *.txt *~ + rm -rf boot install + diff --git a/themes/SuSE/background.pcx b/themes/SuSE/background.pcx Binary files differnew file mode 100644 index 0000000..7c72530 --- /dev/null +++ b/themes/SuSE/background.pcx diff --git a/themes/SuSE/boot.config b/themes/SuSE/boot.config new file mode 100644 index 0000000..9897c06 --- /dev/null +++ b/themes/SuSE/boot.config @@ -0,0 +1,26 @@ +%% include system.inc + +% no splash +/bsplash.show { } def +/bsplash.done { } def + +%% include common.inc + +%% include po/text.inc +%% include window.inc +%% include button.inc +%% include help.inc +%% include main.inc +%% include xmenu.inc +%% include dia_video.inc +%% include dia_splash.inc +%% include dia_lang.inc +%% include dia_dud.inc +%% include dia_help.inc +%% include dia_profile.inc +%% include dia_install.inc +%% include panel.inc +%% include keytables.inc +%% include locale.inc + + diff --git a/themes/SuSE/bsplash.inc b/themes/SuSE/bsplash.inc new file mode 100644 index 0000000..2f1f4da --- /dev/null +++ b/themes/SuSE/bsplash.inc @@ -0,0 +1,95 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% Boot loader splash code. +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Some global vars. + +% Boot loader splash areas to uncover. +% +/bsplash.areas [ + [ 0 130 640 220 true ] + [ 20 20 50 100 false ] + [ 120 30 150 30 false ] + [ 330 80 140 30 false ] + [ 420 20 170 30 false ] + [ 30 420 110 40 false ] + [ 130 370 160 40 false ] + [ 310 440 160 30 false ] + [ 470 380 140 60 false ] +] def + +% start value +/rand.start time def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Generate pseudo random number. +% Good enough for boot loader splash screen. +% +% ( ) ==> ( int ) +% +/rand { + rand.start 59 mul 97 add 0x7fffffff and + /rand.start over def +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Show boot loader splash. +% +% ( ) ==> ( ) +% +/bsplash.show { + currentimage + + "splash.pcx" findfile setimage loadpalette + /max_image_colors max_image_colors image.colors max def + +% 7 0xffffff setpalette +% 0 0 moveto 0 0 image.size image + + % center image + image.size screen.size exch 4 -1 roll sub 2 div 3 1 roll exch sub 2 div + /bsplash.y exch def + /bsplash.x exch def + + bsplash.areas 0 get + dup 0 get over 1 get moveto currentpoint bsplash.x bsplash.y rmoveto + 2 index 2 get 3 index 3 get 5 -1 roll pop image + 500000 usleep + + { + bsplash.areas rand over length mod get + dup 4 get { + pop + } { + dup 0 get over 1 get moveto currentpoint bsplash.x bsplash.y rmoveto + 2 index 2 get 3 index 3 get 5 -1 roll 4 true put image + 50000 usleep + } ifelse + + true + 0 1 bsplash.areas length 1 sub { + bsplash.areas exch get 4 get and + } for + { exit } if + } loop + + setimage +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Just wait. +% +% ( ) ==> ( ) +% +/bsplash.done { + 3000000 usleep +} def + + diff --git a/themes/SuSE/button.inc b/themes/SuSE/button.inc new file mode 100644 index 0000000..3f88054 --- /dev/null +++ b/themes/SuSE/button.inc @@ -0,0 +1,116 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% button handling +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Button templates. +% +% [ x y width height label selected hotkey action ] +% +/button.ok { [ 0 0 85 25 txt_ok false 0 0 ] } def +/button.cancel { [ 0 0 85 25 txt_cancel false keyEsc 0 ] } def +/button.reboot { [ 0 0 85 25 txt_reboot false 0 0 ] } def +/button.continue { [ 0 0 85 25 txt_continue false 0 0 ] } def +/button.eject { [ 0 0 85 25 "Eject" false 0 0 ] } def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Set default button. +% +% ( button ) => ( button ) +% +/button.default { + dup 5 true put +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Make it _not_ the default button. +% +% ( button ) => ( button ) +% +/button.notdefault { + dup 5 false put +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Set button position. +% +% ( button x y ) ==> ( button ) +% +/button.moveto { + rot dup 0 5 -1 roll put exch over 1 rot put +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Assign action to button. +% +% ( button action ) => ( button ) +% +/button.setaction { + over 7 rot put +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Draw button. +% +% ( button ) ==> ( ) +% +/button.show { + /bt.x over 0 get def + /bt.y over 1 get def + /bt.width over 2 get def + /bt.height over 3 get def + /bt.text over 4 get def + /bt.default exch 5 get def + + bt.text strsize + bt.height sub neg 2 div /bt.y.textofs exch def + bt.width sub neg 2 div /bt.x.textofs exch def + + bt.x bt.y moveto + currentpoint currentpoint currentpoint + + currentpoint bt.width bt.height window.current .color.bg get setcolor fillrect moveto + + bt.default { + black black + } { + window.current .color.bg get dup + } ifelse + bt.width bt.height drawborder + moveto 1 1 rmoveto white black bt.width 2 sub bt.height 2 sub drawborder + moveto + % 2 2 rmoveto white black bt.width 4 sub bt.height 4 sub drawborder + + window.current .color.fg get setcolor + moveto bt.x.textofs bt.y.textofs rmoveto bt.text show +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Press button. +% +% ( button ) ==> ( ) +% +/button.press { + /bt.x over 0 get def + /bt.y over 1 get def + /bt.width over 2 get def + /bt.height exch 3 get def + + bt.x 3 add bt.y 3 add moveto + bt.width 7 sub bt.height 7 sub savescreen + 1 1 rmoveto dup restorescreen free + + bt.x 1 add bt.y 1 add moveto black white bt.width 2 sub bt.height 2 sub drawborder + % bt.x 2 add bt.y 2 add moveto black white bt.width 4 sub bt.height 4 sub drawborder +} def + + diff --git a/themes/SuSE/common.inc b/themes/SuSE/common.inc new file mode 100644 index 0000000..d3d85a6 --- /dev/null +++ b/themes/SuSE/common.inc @@ -0,0 +1,1282 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% Main part. +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% input event handling +% +% ( key ) ==> ( input_buffer menu_entry action ) +% +% key +% bit 0-7 ascii +% bit 8-15 scan code +% bit 16-32 status bits (ctrl, shift...) +% +% action +% 0: ok, stay in input loop +% 1: switch to text mode +% >=2: start linux +% +/KeyEvent { + % timeout + + dup 0 eq { boot.buf buildcmdline 2 return } if + + debug 4 ge { + % print keycode somewhere + -1 settransparentcolor + black setcolor + 500 0 moveto dup print " " print + } if + + dup 0xff00 and 16 shl over 0xff and dup 0xe0 eq { pop 0 } if add /key exch def + 16 shr 0xffff and /keystat exch def + + key + + config.keymap { mapkey } if + + dup 0xffffff and dup { exch } if pop + + % for tests + dup keyShiftF1 eq { pop 0x00e4 } if + dup keyShiftF2 eq { pop 0x16d6 } if + dup keyShiftF3 eq { pop 0x8db3 } if + + debug 4 ge { + % print mapped key somewhere + -1 settransparentcolor + black setcolor + 500 20 moveto dup print " " print + } if + + % some special keys + debug.input + + % put key through normal input queue + window.input + + pop + + window.action actExit eq { + /window.action actNothing def + "" -1 1 return + } if + + window.action actCloseInfo eq { + /window.action actNothing def + "" -1 3 return + } if + + window.action actPassword eq { + /window.action actNothing def + password.buf -1 3 return + } if + + window.action actStart eq { + /window.action actNothing def + boot.buf buildcmdline 2 return + } if + + window.action actRedraw eq { + /window.action actNothing def + main.redraw + } if + + window.action actRedrawPanel eq { + /window.action actNothing def + panel.show + } if + + window.action actInstallOK eq { + /window.action actNothing def + install.ok + } if + + window.action actInstallCancel eq { + /window.action actNothing def + install.cancel + } if + + boot.buf menu.entry 0 +} def + + +/bc.cmd 256 string def + +% ( option_string ) ==> ( cmdline menu_entry ) +% +% grub: +% just return +% +% syslinux & lilo: +% check if the commmand line starts with the current kernel name or +% "linux"; if not, put the kernel name in front of the command line. (This +% is to keep compatibility with the old scheme requiring the user to write +% the kernel name explicitly.) +% +/buildcmdline { + menu.entry 0 lt { -1 return } if + menu.entry menu.texts length ge { -1 return } if + + /bc.opts exch def + /bc.kernel menu.texts menu.entry get def + + grub { + + /bc.addkernel false def + + } { + + /bc.addkernel true def + + [ bc.kernel "linux" ] 0 over length 1 sub 1 exch { + over exch get + + bc.opts over eq { + /bc.addkernel false def + } { + bc.opts over strstr 1 eq { + bc.opts over length get ' ' eq { + /bc.addkernel false def + } if + } if + } ifelse + + pop + + bc.addkernel not { exit } if + + } for + + pop + + % special case: option is identical to label + bc.kernel "apic" eq { /bc.addkernel true def } if + + } ifelse + + bc.addkernel { + alt.kernel "" ne { alt.kernel } { bc.kernel } ifelse + "%s " bc.cmd sprintf + } { + bc.cmd 0 0 put + } ifelse + + cmdline.hidden "" ne { + cmdline.hidden "%s " bc.cmd dup length add sprintf + } if + + syslinux { + xmenu.video 0 get 0 eq { + "textmode=1 " bc.cmd dup length add sprintf + } if + video.modes.list xmenu.video 0 get get 0 get dup { + "vga=0x%x " bc.cmd dup length add sprintf + } { + pop + } ifelse + } if + + do_driverupdate { + "dud=1 " bc.cmd dup length add sprintf + } if + + % add splash only if an entry already exists + bc.cmd "splash" bootopt.find dup .undef ne { + % remove existing entry + dup skipnonspaces skipspaces strcpy pop + + % append new entry + xmenu.splash .xm_current get splash.options exch get + "%s " bc.cmd dup length add sprintf + } { + pop + } ifelse + + xmenu.profile { + profile.options xmenu.profile .xm_current get get dup "" ne { + "%s " bc.cmd dup length add sprintf + } { pop } ifelse + } if + + xmenu.install { + install.option "" ne { + install.option "%s " bc.cmd dup length add sprintf + } if + } if + + bc.opts "%s " bc.cmd dup length add sprintf + + bc.cmd dropspaces + + debug 3 ge { + 0 0 moveto black setcolor + bc.cmd print "<< (press ESC) " print trace + } if + + bc.cmd menu.entry +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% ( menu_entries_array cmdline_args_array defaultentry ) == > ( ) +/MenuInit { + bsplash.done + + 0 setcolor 0 0 moveto screen.size fillrect loadpalette + init + + /menu.entry -1 def + + /menu.dentry exch def + /menu.args exch def + /menu.texts exch def + + window.main + dup window.init + window.show + +% fadein_logo + + syslinux usernote 0 ne and { + dvd_popup + } if + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Setup boot option input field. +% +% ( ) == > ( ) +% +/bootoptions.init { + window.current .color.fg get setcolor + window.current .ed.font get setfont + boot.ed edit.hidecursor + menu.args menu.entry get + menu.texts menu.entry get + bootpromptmap + dup + boot.ed exch edit.init + "" ne { boot.ed ' ' edit.input } if +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Split command line into hidden and normal part. +% +% ( cmdline_args menu_text ) == > ( new_cmdline_args ) +% +% alt.kernel is set if a different kernel should be used (this feature should +% no longer be needed). +% +/bootpromptmap { + /alt.kernel "" def + +% syslinux { +% dup "apic" eq { pop pop "apic" /alt.kernel "linux" def return } if +% } if + pop + + /cmdline exch def + + cmdline "showopts" getoption + dup "" eq { + cmdline.shown 0 0 put + pop cmdline "%s" 256 cmdline.shown snprintf + cmdline.hidden 0 0 put + } { + "showopts" length add skipspaces + "%s" 256 cmdline.shown snprintf + cmdline "%s" 256 cmdline.hidden snprintf + cmdline.hidden "showopts" getoption 0 0 put + } ifelse + + cmdline.shown dropspaces + cmdline.hidden dropspaces + + cmdline.shown +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Skip leading non-spaces. +% +% ( string ) ==> ( string ) +% +/skipnonspaces { + { dup 0 get dup 0 ne exch ' ' ne and { 1 add } { exit } ifelse } loop +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Skip leading spaces. +% +% ( string ) ==> ( string ) +% +/skipspaces { + { dup 0 get ' ' eq { 1 add } { exit } ifelse } loop +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Drop spaces at string end. +% Modifies string! +% +% ( string ) ==> ( ) +% +/dropspaces { + dup length + dup 0 eq { + pop pop + } { + 1 sub + -1 0 { + over over get ' ' eq { over exch 0 put } { pop exit } ifelse + } for + pop + } ifelse +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Test if string[ofs-1]/string[ofs] is a word boundary. +% +% ( string ofs ) ==> ( true|false ) +% +% boundary is either space/non-space or non-space/(space|'=') +% +/iswordboundary { + dup 0 eq { pop pop true return } if + + add dup 1 sub 0 get exch 0 get + + over ' ' eq over ' ' gt and { pop pop true return } if + over ' ' gt over dup ' ' eq exch dup '=' eq exch 0 eq or or and { pop pop true return } if + + pop pop false +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Get boot option. +% +% ( cmdline option_name ) ==> ( option_start ) +% +/getoption { + /go.name exch def + /go.cmdline exch def + /go.pos 0 def + { + go.cmdline go.pos add go.name strstr dup { + 1 sub /go.pos exch def + + go.cmdline go.pos iswordboundary + go.cmdline go.pos go.name length add iswordboundary + and { + go.cmdline go.pos add exit + } { + /go.pos go.pos 1 add def + } ifelse + } { + pop "" exit + } ifelse + } loop +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +/redrawmenu { + menu.visible.entries menu.texts length lt menu.scrollbar and { + /menu.vsb.height1 + menu.shift + menu.sb.height mul menu.texts length div + def + + /menu.vsb.height3 + menu.texts length menu.visible.entries menu.shift add sub + menu.sb.height mul menu.texts length div + def + + lightgray setcolor + menu.sb.x menu.sb.y menu.vsb.height1 add moveto + menu.sb.width menu.sb.height menu.vsb.height1 menu.vsb.height3 add sub + fillrect + + menu.vsb.height1 0 ne { + menu.sb.x menu.sb.y moveto + currentpoint menu.sb.width menu.vsb.height1 image + } if + + menu.vsb.height3 0 ne { + menu.sb.x menu.sb.y menu.sb.height menu.vsb.height3 sub add moveto + currentpoint menu.sb.width menu.vsb.height3 image + } if + + } if + + menu.text.normal setcolor + + /x menu.start.x def + /y menu.start.y def + + 0 1 menu.visible.entries 1 sub { + x y moveto currentpoint menu.bar.width menu.bar.height image + x menu.text.xofs add y menu.text.yofs add moveto + menu.texts exch menu.shift add get menuitemmap + currentfont exch font.large setfont show setfont + /y y menu.item.height add def + } for + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% ( entry status ) ==> ( ) +% +% status: +% false not selected +% true selected +% +/MenuSelect { + /menu.status exch def + + /menu.idx over def + + menu.shift sub + menu.item.height mul menu.start.y add + menu.start.x exch + moveto + + currentpoint + menu.status { + menu.bar.color + setcolor menu.bar.width menu.bar.height fillrect + } { + currentpoint menu.bar.width menu.bar.height image + } ifelse + moveto + + menu.text.xofs menu.text.yofs rmoveto + menu.status { + menu.text.select + } { + menu.text.normal + } ifelse + setcolor + menu.texts menu.idx get menuitemmap + currentfont exch font.large setfont show setfont + + menu.status { + % init boot options + keepbootoptions .undef eq { bootoptions.init } if + + % set help context + "main" help.setcontext + menu.texts menu.idx get + dup help.findpage "" eq { + pop + } { + help.setcontext + } ifelse + } if + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% ( text errorcode ) ==> ( ) +% errorcode: +% 0 normal info +% 1 fatal error +% 2 missing kernel +% 3 disk change +% 4 disk change failed +% + +/info.tmpmsg 127 string def + +/InfoBoxInit { + /info.type exch def + /info.msg exch def + + window.dialog + + info.type 1 eq { + dup .title.bg red put + dup .title txt_error_title put + dup .buttons + [ + button.reboot button.default actCloseInfo button.setaction + ] put + } { + dup .title txt_info_title put + dup .buttons + [ + button.ok button.default actCloseInfo button.setaction +% button.cancel button.notdefault actCloseInfo button.setaction + ] put + } ifelse + + syslinux + info.type 2 eq and + usernote 0 ne and { + txt_dvd_warning info.msg + over length info.msg length 1 add add "%s%s" exch + dup string dup /info.msg exch def snprintf + } if + + syslinux info.type 3 eq and { + dup .title txt_change_disk_title put + 0 getinfo 1 add txt_insert_disk info.tmpmsg sprintf + /info.msg info.tmpmsg def + } if + + syslinux info.type 4 eq and { + dup .title txt_change_disk_title put + 1 getinfo 15 not and { + 0 getinfo 1 add + txt_insert_disk3 info.tmpmsg sprintf + } { + 0 getinfo 1 add 1 getinfo 1 add + txt_insert_disk2 info.tmpmsg sprintf + } ifelse + /info.msg info.tmpmsg def + } if + + dup .text info.msg put + + dup window.init + window.show + +} def + + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +% progress bar code + + +% Show percentage of progress bar. +% +% ( percentage ) ==> ( ) +% +/progress.percent { + 0 max 100 min % so people don't ask silly questions... + "100%" strsize over neg progress.text.x add progress.text.y moveto + window.current .color.bg get setcolor + fillrect + + "%3u%%" 8 dup string dup 5 1 roll snprintf + + dup strsize pop neg progress.text.x add progress.text.y moveto + window.current .color.fg get setcolor + dup show + free + +} def + + +% Show n-th progress bar symbol. +% +% ( n ) ==> ( ) +% +/progress.sym.show { + /progress.sym.current exch def + + progress.bar.x progress.bar.y moveto + progress.sym.width progress.sym.current 1 sub mul 1 add 1 rmoveto + progress.sym.width 2 sub + progress.bar.height 2 sub + loading_color setcolor + fillrect + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% ( kernel_name ) ==> ( ) +/ProgressInit { + /progress.kname exch def + + boot.ed edit.hidecursor + + /dia window.dialog def + + dia .width.min 330 put + dia .position 10 put + + dia .title txt_load_kernel_title put + dia .text + progress.kname "memtest" eq { + txt_load_memtest + } { + txt_load_kernel + } ifelse + put + + dia window.init + dia window.show + + % now add progress bar + + dia .x get dia .y get moveto + dia .text.x get dia .text.y get 28 add rmoveto + + /progress.bar.height 19 def + /progress.bar.width dia .width get 60 sub def + + /progress.sym.width 10 def + /progress.bar.width + progress.bar.width progress.sym.width div + /progress.syms over def progress.sym.width mul + def + + currentpoint over 1 sub over 2 sub moveto + black white progress.bar.width 2 add progress.bar.height 4 add drawborder + + /progress.bar.y exch def + /progress.bar.x exch def + + /progress.text.x progress.bar.x progress.bar.width 37 add add def + /progress.text.y progress.bar.y progress.bar.height fontheight sub 2 div add def + + /progress.sym.current 0 def + + 0 progress.percent + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% ( ) ==> ( ) +/ProgressDone { + window.done +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% ( max current ) ==> ( ) +/ProgressUpdate { + over over 100 mul exch 1 max div progress.percent + + progress.syms mul progress.syms 2 div add exch 1 max div + + 0 max progress.syms min + + dup progress.sym.current gt { + progress.sym.current 1 add over 1 exch { + progress.sym.show + } for + } if + pop + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% ( timeout time ) ==> ( ) +/Timeout { + % first time + timeout.time .undef eq { timeout.init } if + + dup /timeout.time exch def + + over sub neg timeout.symbols mul exch div + + dup timeout.current eq { pop return } if + + /timeout.last timeout.current def + /timeout.current exch def + + timeout.current timeout.symbols ge { + timeout.x timeout.time.y moveto + currentpoint timeout.dx timeout.symbols mul fontheight image + 0 1 timeout.symbols 1 sub { + timeout.clear { 2 } { 1 } ifelse drawtsymbol + } for + } { + timeout.time.x timeout.time.y moveto + currentpoint currentpoint 100 fontheight image + moveto + white setcolor + timeout.time 10 mul 150 add 182 div "%ds" 64 timeout.buf snprintf timeout.buf show + timeout.last 1 timeout.current { + 1 sub dup 0 ge { + 1 drawtsymbol + } if + } for + } ifelse +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% draw a timeout symbol +% ( index status ) ==> () +% +% status: 0: init, 1: clear, 2: set +% +/drawtsymbol { + /timeout.status exch def + dup timeout.dx mul timeout.x add exch + timeout.dy mul timeout.y add + moveto currentpoint + timeout.status 2 eq { + currentpoint timeout.size image + } { + timeout.status 0 eq { + pop pop + } { + 0 462 timeout.size image + } ifelse + } ifelse +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% ( time ) ==> ( ) +% /Timer { pop } def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% ( label correct_password ) ==> ( ) +% +/PasswordInit { + /password.key exch def pop + + /dia window.dialog def + + dia .title txt_password_title put + dia .text txt_password put + dia .buttons + [ button.ok button.default actPassword button.setaction ] + put + + dia window.init + dia window.show + + % add input field + + % show only '*' + % dia .ed.font dia .font get 0x80 or put + + dia .x get dia .y get moveto + dia .text.x get dia .text.y get 30 add rmoveto + + /password.ed.width dia .width get 20 sub def + /password.ed.height dia .ed.font get setfont fontheight 2 add def + + currentpoint over 1 sub over 2 sub moveto + black white password.ed.width password.ed.height 4 add drawborder + moveto + + black setcolor + + dia .ed [ + currentpoint + password.ed.width password.ed.height savescreen + password.buf + password.buf.size + 0 + 0 + 0 + ] put + + dia .ed get "" edit.init +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% ( password ) ==> ( error ) +% +% error: +% true password ok +% false wrong password +% +% ****** FIXME: test result seems to be unused +% +/PasswordDone { + + password.key eq +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% ( text ) == > ( new_text ) +/menuitemmap { + dup "memtest" eq over "memtest86" eq or { pop txt_memtest return } if + syslinux { + dup "linux" eq { pop txt_install return } if + dup "failsafe" eq { pop txt_safe_install return } if + dup "noacpi" eq { pop txt_noacpi_install return } if + dup "manual" eq { pop txt_manual_install return } if + dup "rescue" eq { pop txt_rescue return } if + dup "hwcheck" eq { pop "Hardware Check" return } if + dup "harddisk" eq { pop txt_boot_harddisk return } if + dup "eval" eq { pop "LiveEval" return } if + } { + dup "linux" eq { pop "Linux" return } if + dup "failsafe" eq { pop txt_safe_linux return } if + dup "windows" eq { pop "Windows" return } if + } ifelse +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% ( color0 color1 width height ) ==> ( ) +/drawborder { + currentpoint /db.y0 exch def /db.x0 exch def + + /db.y1 exch 1 sub db.y0 add def + /db.x1 exch 1 sub db.x0 add def + /db.col1 exch def + /db.col0 exch def + + db.x0 db.y1 moveto + + db.col0 setcolor + db.x0 db.y0 lineto db.x1 db.y0 lineto + + db.col1 setcolor + db.x1 db.y1 lineto db.x0 db.y1 lineto +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% ( color0 color1 color2 width height ) ==> ( ) +% draw frame with shadow +% color0: upper left, color1: lower right, color2: shadow +/drawborder3 { + currentpoint /db.y0 exch def /db.x0 exch def + + /db.y1 exch 1 sub db.y0 add def + /db.x1 exch 1 sub db.x0 add def + /db.col2 exch def + /db.col1 exch def + /db.col0 exch def + + db.x0 db.y1 moveto + + db.col0 setcolor + db.x0 db.y0 lineto db.x1 db.y0 lineto + + db.col1 setcolor + db.x1 db.y1 lineto db.x0 db.y1 lineto + + db.col2 -1 ne { + db.col2 setcolor + 1 1 rmoveto + db.x1 1 add db.y1 1 add lineto + db.x1 1 add db.y0 1 add lineto + } if +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% center text +% ( text width height ) ==> ( ) +/centertext { + 3 -1 roll strsize + 4 2 roll + 4 1 roll exch 4 1 roll sub 2 div neg 3 1 roll sub 2 div neg +} def + + +/fadeout_logo { + /cols 256 malloc def + + 0 1 255 { cols exch 0 put } for + + 10 1 150 { + 10 1 100 { + over exch moveto getpixel + cols exch 1 put + } for + pop + } for + cols 10 10 moveto getpixel 0 fade +} def + +/fadein_logo { + cols 10 10 moveto getpixel fadein +} def + + +% Allocate and define a new color. +% +% ( palette ) ==> ( color ) +% +/newcolor { + colorbits 8 le { + newcolor.count .undef eq { /newcolor.count 0 def } if + max_image_colors newcolor.count add + dup rot setpalette + /newcolor.count newcolor.count 1 add def + } if + def +} def + + +/init { + 0 0 moveto currentpoint clip.size image + + % set default language + "lang" findfile dup { + /tmp over length 1 add string def + tmp exch { + dup ' ' eq over '\n' eq or { pop pop exit } if + over exch 0 exch put + 1 add + } forall + tmp setlang pop + } { + pop + "en" setlang pop + } ifelse + + font.large setfont + + /menu.text.xofs 10 def + /menu.text.yofs 2 def + /menu.item.height fontheight dup 3 div add def + /menu.bar.height fontheight menu.text.yofs dup add add def + + font.normal setfont + + /menu.text.normal white def + /menu.text.select white def + /boot.text.options white def + /boot.text.normal white def + /infobox.bg lightgray def + /infobox.text.normal black def + /frame.darkcolor grayb5 def + /frame.lightcolor graye8 def + /frame.shadowcolor mediumblue def + + /menu.bar.color fn_color def + + /frame1.pos { 160 100 } def + /frame1.size { 320 195 } def + /frame2.pos { 10 410 } def + /frame2.size { 620 25 } def + /frame3.pos { 10 386 } def + /frame3.size { 124 25 } def + /frame4.pos { 560 62 } def + /frame4.size { 22 264 } def + + /menu.start.x frame1.pos pop 10 add def + /menu.start.y frame1.pos exch pop 12 add def + + /menu.bar.width frame1.size pop 20 sub def + /menu.max.entries 8 def + /menu.scrollbar false def + + /boot.buf.size 256 def + /boot.buf boot.buf.size string def + + /ms.size { 22 22 } def + /ms.up { 0 480 } def + /ms.down { 23 480 } def + + % password buffer + /password.buf.size 32 def + /password.buf password.buf.size string def + + /update.text txt_dud_ready def + /update.pos { 260 383 } def + + frame1.pos moveto prog_frame_color dup prog_frame_color2 frame1.size drawborder3 + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Some special debug & test keys. +% +% ( key_in ) ==> ( key_out ) +% +/debug.input { +% dup keyShiftF4 eq { +% 0 0 moveto +% 16 string dup dup "1234" ">%s<" 2 index sprintf show free +% pop 0 +% } if + + dup keyF7 eq syslinux and { + "kroete.data" findfile kroete.dir idle + /kroete.dir kroete.dir 1 xor def + pop 0 + } if + + dup keyF8 eq syslinux and { + .undef 0 idle + pop 0 + } if + + dup keyShiftF3 eq syslinux and debug 3 ge and { + currentcolor black setcolor + currentpoint 0 0 moveto + "eject " print bootdrive eject print + moveto setcolor + pop 0 + } if + + dup keyShiftF5 eq syslinux and debug 3 ge and { + currentcolor black setcolor + currentpoint 100 0 moveto + bootdrive print + moveto setcolor + pop 0 + } if + + dup keyShiftF8 eq debug 3 ge and { + currentcolor black setcolor currentpoint 300 0 moveto + memsize print "/" print print " " print + moveto setcolor + pop 0 + } if + + dup keyShiftF9 eq debug 3 ge and { + pop 0 + } if + + dup keyShiftF10 eq { + /debug debug 1 add def "" + pop 0 + } if + + dup keyShiftF11 eq { + currenttransparency 0x10 sub 0 max settransparency + pop 0 + } if + + dup keyF11 eq { + + 0 1 479 { + 0 1 639 { + over moveto + currentpoint 3 div 8 shl exch 3 div add setcolor + putpixel + } for + pop + } for + + pop 0 + } if + + dup keyShiftF12 eq { + currenttransparency 0x10 add 0x100 min settransparency + pop 0 + } if + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Show exit popup. +% +% ( ) ==> ( ) +% +/exit_popup { + window.dialog + + dup .title txt_exit_title put + dup .text txt_exit_dialog put + dup .buttons [ + button.ok button.default actExit button.setaction + button.cancel button.notdefault actNothing button.setaction + ] put + dup window.init + window.show + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Show help window. +% +% ( ) ==> ( ) +% +/show_help { + window.help + + dup window.init + window.show + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Show dvd popup. +% +% ( ) ==> ( ) +% +/dvd_popup { + window.dialog + + dup .title txt_dvd_warning_title put + dup .text txt_dvd_warning2 put + dup .buttons [ +% button.eject button.default actEject actNoClose or button.setaction + button.continue button.default actNothing button.setaction + ] put + dup window.init + window.show + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Show "power off" popup. +% +% ( ) ==> ( ) +% +/power_off { + window.dialog + + dup .title txt_power_off_title put + dup .text txt_power_off put + dup .buttons [ + button.ok button.notdefault actPowerOff actNoClose or button.setaction + button.cancel button.default actNothing button.setaction + ] put + dup window.init + window.show + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Initialize timeout indicator. +% +% ( ) ==> ( ) +% +/timeout.init { + /timeout.current -1 def + /timeout.x 160 def + /timeout.y 340 def + /timeout.dx 1 def + /timeout.dy 0 def + /timeout.symbols 320 def + /timeout.clear true def + /timeout.size { 1 18 } def + /timeout.buf 64 string def + + timeout.x timeout.y moveto + prog_frame_color dup + timeout.dx timeout.symbols mul timeout.size exch pop + drawborder + + timeout.x timeout.y 20 sub moveto + white setcolor + "booting in " show + currentpoint /timeout.time.y exch def /timeout.time.x exch def +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Search for option in cmdline. +% Returns .undef if not found. +% +% ( cmdline option_name ) ==> ( option_start ) +% +/bootopt.find { + /bo.opt exch def + /bo.cmdline exch def + + { + bo.cmdline bo.opt strstr + dup { + dup 1 eq { + true + } { + dup 2 sub bo.cmdline exch get ' ' eq + } ifelse + + { + bo.cmdline over bo.opt length add 1 sub get + dup '=' eq + over ' ' eq or + exch 0 eq or + } { + false + } ifelse + + bo.cmdline rot add exch + + { + 1 sub exit + } { + /bo.cmdline exch def + } ifelse + } { + pop + .undef exit + } ifelse + } loop + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Global variables. +% + +/clip.size { 640 480 } def + +640 480 8 findmode setmode not { false return } if +% 800 600 8 findmode setmode not { false return } if + +"background.pcx" findfile setimage loadpalette +/max_image_colors image.colors def + +% 7 dup 0xffffff setpalette setcolor + +bsplash.show + +% color & font definitions must be global + +/black 0x000000 newcolor +/white 0xffffff newcolor +/mediumblue 0x566eb2 newcolor +/mediumblue2 0x768cc5 newcolor +/lightblue 0xd0d0ff newcolor +/lightblue2 0x2a73d3 newcolor +/darkgray 0x4c4c4c newcolor +/grayb5 0xb5b5b5 newcolor +/lightgray 0xececf4 newcolor +/graye8 0xe8e8e8 newcolor +/blue 0x0000a0 newcolor +/yellow 0xffff20 newcolor +/red 0xc00000 newcolor +/somered 0xe6373a newcolor +/loading_color 0x23449c newcolor +/green 0x009000 newcolor +/fn_color 0x33449c newcolor +/fn_color2 0x53a53f newcolor +/prog_frame_color lightblue def +/prog_frame_color2 0x364c65 newcolor +/dud_color 0x006f64 newcolor + +/font.normal "16x16.font" findfile def +/font.large font.normal def + +/cmdline.hidden 256 string def +/cmdline.shown 256 string def + +/kroete.dir 0 def + +/debug 0 def + + diff --git a/themes/SuSE/dia_dud.inc b/themes/SuSE/dia_dud.inc new file mode 100644 index 0000000..6772e28 --- /dev/null +++ b/themes/SuSE/dia_dud.inc @@ -0,0 +1,59 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% Driver update dialog. +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Show driver update. +% +% ( ) => ( ) +% +/panel.dud { + do_driverupdate .undef eq { + /do_driverupdate 1 def + 1 updatedisk + black setcolor + currentfont font.normal setfont + update.pos moveto currentpoint + prog_frame_color dup prog_frame_color2 + update.text strsize 6 add exch 16 add exch + drawborder3 + moveto 8 3 rmoveto update.text white setcolor show + setfont + } + { + /do_driverupdate .undef def + 0 updatedisk + update.pos moveto currentpoint + update.text strsize 7 add exch 17 add exch + image + } ifelse + + "driverupdate" help.setcontext +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Return width of driver update entry. +% +% ( ) => ( width ) +% +/panel.dud.width { + txt_driver_update strsize pop +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Redraw panel entry. +% +% ( panel ) => ( ) +% +/panel.dud.update { + panel.text.moveto + + txt_driver_update show +} def + + diff --git a/themes/SuSE/dia_help.inc b/themes/SuSE/dia_help.inc new file mode 100644 index 0000000..cb8cd24 --- /dev/null +++ b/themes/SuSE/dia_help.inc @@ -0,0 +1,44 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% Panel help entry. +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Show help window. +% +% ( ) => ( ) +% +/panel.help { + help.context "opt" eq { + findbootoption + help.mapcontext + dup help.findpage + "" eq { pop } { help.setcontext } ifelse + } if + show_help +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Return width of help entry. +% +% ( ) => ( width ) +% +/panel.help.width { + txt_help strsize pop +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Redraw panel entry. +% +% ( panel ) => ( ) +% +/panel.help.update { + panel.text.moveto + + txt_help show +} def + + diff --git a/themes/SuSE/dia_install.inc b/themes/SuSE/dia_install.inc new file mode 100644 index 0000000..ad3d2b6 --- /dev/null +++ b/themes/SuSE/dia_install.inc @@ -0,0 +1,290 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% Install mode selection dialog. +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Some global vars. +% +/install.last 0 def + +/install.option 255 string def + +% install types +/.inst_cdrom 0 def +/.inst_slp 1 def +/.inst_ftp 2 def +/.inst_nfs 3 def +/.inst_smb 4 def +/.inst_hd 5 def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Build install mode list. +% +% ( ) ==> ( ) +% +/install.init { + /xmenu.install .xm_size array def + + /xmenu xmenu.install def + + xmenu .xm_current 0 put + + % see install types (.inst_*) + xmenu .xm_list [ "CD-ROM" "SLP" "FTP" "NFS" "SMB" txt_harddisk ] put + + pmenu.init +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Update install mode. +% +% ( ) ==> ( ) +% +/install.update { + /xmenu xmenu.install def + + xmenu .xm_current get dup .inst_cdrom eq exch .inst_slp eq or { + /install.last xmenu .xm_current get def + + install.option install.last .inst_cdrom eq { "" } { "install=slp" } ifelse strcpy + + /window.action actRedrawPanel def + + pmenu.update + } { + install.dialog + } + ifelse +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Show install menu. +% +% ( ) => ( ) +% +/panel.install { + "install_src" help.setcontext + + window.xmenu + dup .xmenu xmenu.install put + dup .xmenu.update /install.update put + dup window.init + window.show +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Return width of panel entry. +% +% ( ) => ( width ) +% +/panel.install.width { + /xmenu xmenu.install def + + pmenu.width +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Redraw panel entry. +% +% ( panel ) => ( ) +% +/panel.install.update { + /xmenu xmenu.install def + + pmenu.panel.update +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +/install.dialog { + + /dia window.dialog def + + xmenu .xm_current get + + dup .inst_hd eq { + input.dialog.hd { + /dia input.dialog.hd def + } { + /input.dialog.hd window.dialog def + /dia input.dialog.hd def + + dia .dont_free 1 put + + dia .title txt_harddisk_title put + dia .text "" put + + % Must all be of same size! + dia .ed.list 2 array put + dia .ed.buffer.list [ 63 string 127 string ] put + dia .ed.text.list [ txt_hd_diskdevice txt_directory ] put + + dia .ed.focus 0 put + } ifelse + } if + + dup .inst_ftp eq { + input.dialog.ftp { + /dia input.dialog.ftp def + } { + /input.dialog.ftp window.dialog def + /dia input.dialog.ftp def + + dia .dont_free 1 put + + dia .title txt_ftp_title put + dia .text "" put + + % Must all be of same size! + dia .ed.list 4 array put + dia .ed.buffer.list [ 63 string 127 string 31 string 31 string ] put + dia .ed.text.list [ txt_server txt_directory txt_user1 txt_password ] put + + dia .ed.focus 0 put + } ifelse + } if + + dup .inst_nfs eq { + input.dialog.nfs { + /dia input.dialog.nfs def + } { + /input.dialog.nfs window.dialog def + /dia input.dialog.nfs def + + dia .dont_free 1 put + + dia .title txt_nfs_title put + dia .text "" put + + % Must all be of same size! + dia .ed.list 2 array put + dia .ed.buffer.list [ 63 string 127 string ] put + dia .ed.text.list [ txt_server txt_directory ] put + + dia .ed.focus 0 put + } ifelse + } if + + dup .inst_smb eq { + input.dialog.smb { + /dia input.dialog.smb def + } { + /input.dialog.smb window.dialog def + /dia input.dialog.smb def + + dia .dont_free 1 put + + dia .title txt_smb_title put + dia .text "" put + + % Must all be of same size! + dia .ed.list 4 array put + dia .ed.buffer.list [ 63 string 127 string 31 string 31 string ] put + dia .ed.text.list [ txt_server txt_directory txt_user2 txt_password ] put + + dia .ed.focus 0 put + } ifelse + } if + + pop + + dia .ed.width 240 put + + dia .buttons [ + button.ok button.default actInstallOK actNoClose or button.setaction + button.cancel button.notdefault actInstallCancel button.setaction + ] put + + dia window.init + dia window.show + +} def + + + +/install.ok { + /xmenu xmenu.install def + + window.done + + /install.last xmenu .xm_current get def + + /window.action actRedrawPanel def + + pmenu.update + + xmenu .xm_current get + + dup .inst_hd eq { + input.dialog.hd .ed.buffer.list get + dup 1 get dup 0 get '/' eq { 1 add } if + exch 0 get dup 0 get '/' eq { 1 add } if + "install=hd://%s/%s" install.option sprintf + } if + + dup .inst_ftp eq { + input.dialog.ftp .ed.buffer.list get + + "install=ftp://" install.option sprintf + + % add user name & password + dup 2 get "" ne { + dup 2 get "%s" install.option dup length add sprintf + dup 3 get "" ne { + dup 3 get ":%s" install.option dup length add sprintf + } if + "@" install.option dup length add sprintf + } if + + dup 1 get exch 0 get "%s/%s" install.option dup length add sprintf + } if + + dup .inst_nfs eq { + input.dialog.nfs .ed.buffer.list get + dup 1 get dup 0 get '/' eq { 1 add } if + exch 0 get + "install=nfs://%s/%s" install.option sprintf + } if + + dup .inst_smb eq { + input.dialog.smb .ed.buffer.list get + + "install=smb://" install.option sprintf + + % add user name & password + dup 2 get "" ne { + dup 2 get "%s" install.option dup length add sprintf + dup 3 get "" ne { + dup 3 get ":%s" install.option dup length add sprintf + } if + "@" install.option dup length add sprintf + } if + + dup 1 get exch 0 get "%s/%s" install.option dup length add sprintf + } if + + pop + +} def + + +/install.cancel { + /xmenu xmenu.install def + + xmenu .xm_current install.last put + +% /window.action actRedrawPanel def +% pmenu.update +} def + diff --git a/themes/SuSE/dia_lang.inc b/themes/SuSE/dia_lang.inc new file mode 100644 index 0000000..90d816e --- /dev/null +++ b/themes/SuSE/dia_lang.inc @@ -0,0 +1,90 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% Language selection dialog. +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Build language list. +% +% ( ) ==> ( ) +% +/keytable.init { + /tmp.kt [ keymaps { 1 get } forall ] def + + /xmenu.keytable .xm_size array def + + /xmenu xmenu.keytable def + + xmenu .xm_current keymaps.default put + xmenu .xm_list tmp.kt put + + % start with current lang + + /tmp.kt 0 def + keymaps { + 0 get config.lang eq { xmenu .xm_current tmp.kt put exit } if + /tmp.kt tmp.kt 1 add def + } forall + + pmenu.init +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Update language. +% +% ( ) ==> ( ) +% +/keytable.update { + /xmenu xmenu.keytable def + + keymaps xmenu .xm_current get get 0 get setlang { /window.action actRedraw def } if + /config.keymap keymaps xmenu .xm_current get get 2 get def + + % Why? --> see dia_install.inc; same there. + window.action actRedraw eq { pmenu.update } if +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Show language menu. +% +% ( ) => ( ) +% +/panel.keytable { + "keytable" help.setcontext + + window.xmenu + dup .xmenu xmenu.keytable put + dup .xmenu.update /keytable.update put + dup window.init + window.show +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Return width of panel entry. +% +% ( ) => ( width ) +% +/panel.keytable.width { + /xmenu xmenu.keytable def + + pmenu.width +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Redraw panel entry. +% +% ( panel ) => ( ) +% +/panel.keytable.update { + /xmenu xmenu.keytable def + + pmenu.panel.update +} def + + diff --git a/themes/SuSE/dia_profile.inc b/themes/SuSE/dia_profile.inc new file mode 100644 index 0000000..61c2e24 --- /dev/null +++ b/themes/SuSE/dia_profile.inc @@ -0,0 +1,139 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% Profile selection dialog. +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Some global vars. +% + +% fallback if we can't parse "profiles" +/profile.options [ "" ] def +/profile.items [ "Broken Profiles" ] def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Parse "profiles" file. +% +% ( ) ==> ( ) +% +/profile.parsedata { + /pf.tmp.datalen profile.data length def + /pf.tmp.str profile.data cvs def + + /profile.default 0 def + + pf.tmp.datalen 0 eq { return } if + pf.tmp.str pf.tmp.datalen 1 sub get '\n' ne { return } if + + '\n' seteotchar + + /profile.items [ + + /pf.tmp.len 0 def + /pf.tmp.cnt 0 def + { + pf.tmp.str pf.tmp.len add strdup + dup dup length 0 put + /pf.tmp.len over length 1 add pf.tmp.len add def + + dup 0 get '*' eq { 1 add /profile.default pf.tmp.cnt def } if + + pf.tmp.len pf.tmp.datalen ge { exit } if + + /pf.tmp.cnt inc + } loop + + ] def + + ' ' seteotchar + + /profile.options [ + + profile.items { + dup length add + dup 0 0 put + 1 add + } forall + + ] def + + 0 seteotchar + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Build profile list. +% +% ( ) ==> ( ) +% +/profile.init { + /xmenu.profile .xm_size array def + /xmenu xmenu.profile def + + profile.parsedata + + xmenu .xm_current profile.default put + xmenu .xm_list profile.items put + + pmenu.init +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Update profile. +% +% ( ) ==> ( ) +% +/profile.update { + /xmenu xmenu.profile def + + /window.action actRedrawPanel def + + pmenu.update +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Show profile menu. +% +% ( ) => ( ) +% +/panel.profile { + "profile" help.setcontext + + window.xmenu + dup .xmenu xmenu.profile put + dup .xmenu.update /profile.update put + dup window.init + window.show +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Return width of panel entry. +% +% ( ) => ( width ) +% +/panel.profile.width { + /xmenu xmenu.profile def + + pmenu.width +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Redraw panel entry. +% +% ( panel ) => ( ) +% +/panel.profile.update { + /xmenu xmenu.profile def + + pmenu.panel.update +} def + + diff --git a/themes/SuSE/dia_splash.inc b/themes/SuSE/dia_splash.inc new file mode 100644 index 0000000..9083d06 --- /dev/null +++ b/themes/SuSE/dia_splash.inc @@ -0,0 +1,90 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% Splash mode selection dialog. +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Some global vars. +% +/splash.default 2 def + +/splash.options [ + "splash=0" + "splash=verbose" + "splash=silent" +] def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Build splash list. +% +% ( ) ==> ( ) +% +/splash.init { + /xmenu.splash .xm_size array def + + /xmenu xmenu.splash def + + xmenu .xm_current splash.default put + xmenu .xm_list [ "Native" "Verbose" "Silent" ] put + + pmenu.init +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Update splash mode. +% +% ( ) ==> ( ) +% +/splash.update { + /xmenu xmenu.splash def + + /window.action actRedrawPanel def + + pmenu.update +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Show splash menu. +% +% ( ) => ( ) +% +/panel.splash { + "startup" help.setcontext + + window.xmenu + dup .xmenu xmenu.splash put + dup .xmenu.update /splash.update put + dup window.init + window.show +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Return width of panel entry. +% +% ( ) => ( width ) +% +/panel.splash.width { + /xmenu xmenu.splash def + + pmenu.width +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Redraw panel entry. +% +% ( panel ) => ( ) +% +/panel.splash.update { + /xmenu xmenu.splash def + + pmenu.panel.update +} def + + diff --git a/themes/SuSE/dia_video.inc b/themes/SuSE/dia_video.inc new file mode 100644 index 0000000..73f4c12 --- /dev/null +++ b/themes/SuSE/dia_video.inc @@ -0,0 +1,192 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% Video mode selection dialog. +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Some global vars. +% +% We have kernel splash images for at least these sizes. +/video.splashsizes [ + 640 480 + 800 600 + 1024 768 + 1280 1024 +] def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Create sort key for video modes. +% +% ( vm_index ) ==> ( sort_index ) +% +/vmsortindex { + video.modes.list exch get + dup + 1 get 16 shl + exch 2 get add +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Swap video mode entries. +% (Helper for video mode sorting.) +% +% ( vm_index_1 vm_index_2 ) ==> ( ) +% +/vmsortexch { + over video.modes.list exch get + over video.modes.list exch get + video.modes.list + 5 -1 roll rot put + video.modes.list 3 1 roll put +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Check if we have a splash in that resolution. +% +% ( video_mode_list_entry ) ==> ( true|false ) +% +/video.havesplash { + false exch + + 0 2 video.splashsizes length 1 sub { + over over over + 2 get rot 1 get rot video.splashsizes exch get eq + rot 1 add video.splashsizes exch get rot eq and + { exch pop true exch exit } if + } for + + pop + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Build video mode list. +% +% ( ) ==> ( ) +% +/video.init { + /xmenu.video .xm_size array def + + /xmenu xmenu.video def + + videomodes 1 add dup array /video.modes.text exch def array /video.modes.list exch def + xmenu .xm_list video.modes.text put + + % add text mode entry + + % [ mode width height supported ] + video.modes.list 0 [ 0 0 0 1 ] put + + videomodes 0 gt { + 0 1 videomodes 1 sub { + video.modes.list exch [ over getvideomode ] exch 1 add exch put + } for + } if + + % sort video.modes.list + + video.modes.list length 1 gt { + 0 1 video.modes.list length 2 sub { + dup 1 add 1 video.modes.list length 1 sub { + over vmsortindex over vmsortindex gt { + over over vmsortexch + } if + pop + } for + pop + } for + } if + + % create mode strings + + 0 1 video.modes.list length 1 sub { + video.modes.text exch + dup video.modes.list exch get + dup 1 get 0 eq { + pop "Text Mode" put + } { + 32 string dup rot + dup 2 get exch 1 get + "%d x %d" 32 5 -1 roll snprintf + put + } ifelse + } for + + % select first mode + xmenu .xm_current 0 put + + % select largest mode the monitor supports + + 0 1 video.modes.list length 1 sub { + video.modes.list over get + dup 3 get 0 gt exch video.havesplash and { + xmenu .xm_current rot put + } { + pop + } ifelse + } for + + pmenu.init +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Update video mode. +% +% ( ) ==> ( ) +% +/video.update { + /xmenu xmenu.video def + + /window.action actRedrawPanel def + + pmenu.update +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Show video menu. +% +% ( ) => ( ) +% +/panel.video { + "videomode" help.setcontext + + window.xmenu + dup .xmenu xmenu.video put + dup .xmenu.update /video.update put + dup window.init + window.show +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Return width of video entry. +% +% ( ) => ( width ) +% +/panel.video.width { + /xmenu xmenu.video def + + pmenu.width +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Redraw panel entry. +% +% ( panel ) => ( ) +% +/panel.video.update { + /xmenu xmenu.video def + + pmenu.panel.update +} def + + diff --git a/themes/SuSE/happysuse.mod b/themes/SuSE/happysuse.mod Binary files differnew file mode 100644 index 0000000..9efbefe --- /dev/null +++ b/themes/SuSE/happysuse.mod diff --git a/themes/SuSE/help-boot.cs.html b/themes/SuSE/help-boot.cs.html new file mode 100644 index 0000000..1872a93 --- /dev/null +++ b/themes/SuSE/help-boot.cs.html @@ -0,0 +1,113 @@ +<html><body> + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="help">Používání nápovědy</a></h3> + +Nápověda zavaděče je citlivá na obsah. Poskytuje informace o zvolené nabídce nebo pokud editujete parametry jádra, snaží se poskytnout informace o dané volbě.<br> +<br> +Navigační klávesy<br><br> + + <em>Up Arrow</em>: návrat na předešlý odkaz<br> + <em>Down Arrow</em>: přechod na následující odkaz<br> + <em>Left Arrow</em>, <em>Backspace</em>: návrat k předešlému tématu<br> + <em>Right Arrow</em>, <em>Enter</em>, <em>Space</em>: přejít na označený odkaz<br> + <em>Page Up</em>: o stránku nahoru<br> + <em>Page Down</em>: o stránku dolů<br> + <em>Home</em>: přechod na začátek stránky<br> + <em>End</em>: přechod na konec stránky<br> + <em>Esc</em>: ukončení nápovědy<br> + +<br>Návrat do <a href="#opt">startovací nabídky</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="startup">Splash Mode Selection</a></h3> + +Splash režim můžete měnit pomocí klávesy <em>F3</em>. Použít můžete také parametr jádra <a href="#o_splash">splash</a>.<br> +<br> +<em>native</em> vypne splash screen (stejně jako splash=0)<br> +<br> +<em>silent</em> zakryje všechna hlášení jádra a zobrazí místo toho animaci znázorňující pokrok při stratu nebo ukončení systému<br> +<br> +<em>verbose</em> Zobrazí hlášení jádra na grafickém pozadí<br> + +<br>Návrat do <a href="#opt">startovací nabídky</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="keytable">Výběr klávesové mapy</a></h3> + +Stisknutím klávesy <em>F2</em> získáte seznam klávesových map.<br><br> + +Tato volba je zatím experimentální a nemusí vždy fungovat. +(Proto není <em>F2</em> v zobrazené nabídce.) + +<br><br>Návrat do <a href="#opt">startovací nabídky</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="opt">Parametry</a></h3> + + <a href="#o_splash">splash</a> -- ovládá splash screen<br> + <a href="#o_apm">apm</a> -- nastavení správy napájení<br> + <a href="#o_acpi">acpi</a> -- advanced configuration and power interface<br> + <a href="#o_ide">ide</a> -- ovládání IDE subsystému<br> + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_splash">Parametry jádra: splash</a></h3> + +Splash screen je obrázek znázorňující průběh spouštění a vypínání.<br> +<br> +<em>splash=0</em><br> +Splash screen je vypnutý. Tato volba je velmi užitečná pro staré monitory a v případě problémů.<br> +<br> +<em>splash=verbose</em><br> Splash screen je puštěný, ale stále vidíte hlášení jádra.<br> +<br> +<em>splash=silent</em><br> +Splash screen je puštěný a zcela zakrývá hlášení jádra.<br> +<br> +Návrat do <a href="#opt">startovací nabídky</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_apm">Parametry jádra: apm</a></h3> + +APM je jedním ze standardů správy napájení používaných na současných počítačích. Obvykle je používán například pro uspání na disk u notebooků a také je odpovědný za vypnutí počítače po ukončení operačního systému. APM je závislé na správně fungujícím BIOSu. V případě poškození BIOSu by měla být funkce APM omezena. Z toho důvodu můžete APM vypnout parametrem:<br><br> + + <em>apm=off</em> -- kompletní vypnutí APM<br><br> + +Některé velmi nové počítače místo APM používají +<a href="#o_acpi">ACPI</a>. + +<br><br>Návrat do <a href="#opt">startovací nabídky</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_acpi">Parametry jádra: acpi</a></h3> + +ACPI (Advanced Configuration and Power Interface) je standard definující nastavení napájení a správu zařízení mezi operačním systémem a BIOSem. Ve výchozím nastavení je <em>acpi</em> zapnuto v případě, že jde o BIOS vydaný po roce 2000. Nejčastěji používané nastavení:<br> +<br> + <em>pci=noacpi</em> -- nepoužívat ACPI k předávání PCI přerušení + <em>acpi=oldboot</em> -- aktivní zůstane pouze ta část ACPI, která je potřebná pro start systému<br> + <em>acpi=off</em> -- vypnutí ACPI<br> + <em>acpi=force</em> -- zapnutí ACPI i pro BIOS vydaný před rokem 2000<br> +<br> +Na nových počítačích nahrazuje starší <a href="#o_apm">apm</a> systém. + + +<br><br>Návrat do <a href="#opt">startovací nabídky</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_ide">Parametry jádra: ide</a></h3> + +IDE je na rozdíl od SCSI obvykle používáno na pracovních stanicích. +V případě výskytu problémů s IDE systémem můžete použít parametr: <br><br> + + <em>ide=nodma</em> -- Vypnutí DMA pro všechna IDE zařízení<br> + + + +<br><br>Návrat do <a href="#opt">startovací nabídky</a>. + +</body></html> diff --git a/themes/SuSE/help-boot.en.html b/themes/SuSE/help-boot.en.html new file mode 100644 index 0000000..fd07d53 --- /dev/null +++ b/themes/SuSE/help-boot.en.html @@ -0,0 +1,141 @@ +<html><body> + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="help">Using the Help System</a></h3> + +The boot loader online help is context sensitive. It gives information +about the selected menu item or, if you are editing boot options, +it tries to look up information about the option in which the cursor is +positioned.<br> +<br> +Navigation Keys<br><br> + + <em>Up Arrow</em>: highlight previous link<br> + <em>Down Arrow</em>: highlight next link<br> + <em>Left Arrow</em>, <em>Backspace</em>: return to previous topic<br> + <em>Right Arrow</em>, <em>Enter</em>, <em>Space</em>: follow link<br> + <em>Page Up</em>: scroll up one page<br> + <em>Page Down</em>: scroll down one page<br> + <em>Home</em>: go to page start<br> + <em>End</em>: go to page end<br> + <em>Esc</em>: leave help<br> + +<br>Return to <a href="#opt">Boot Options</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="startup">Splash Mode Selection</a></h3> + +<em>F3</em> lets you change the splash screen mode. You can +use the <a href="#o_splash">splash</a> kernel option directly, if you prefer.<br> +<br> +<em>native</em> turns the splash screen off (same as splash=0)<br> +<br> +<em>silent</em> suppresses all kernel and boot messages and shows a progress +bar instead<br> +<br> +<em>verbose</em> shows nice picture and kernel and boot messages<br> + +<br>Return to <a href="#opt">Boot Options</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="keytable">Language and Keyboard Layout Selection</a></h3> + +Press <em>F2</em> to change language and keyboard layout the boot loader uses. + +<br><br>Return to <a href="#opt">Boot Options</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="profile">Choose Profile</a></h3> + +Press <em>F4</em> to select a profile. Your system will be started using the +configuration saved in this profile. + +<br><br>Return to <a href="#opt">Boot Options</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="opt">Boot Options</a></h3> + + <a href="#o_splash">splash</a> -- influence the behavior of the splash screen<br> + <a href="#o_apm">apm</a> -- toggle power management<br> + <a href="#o_acpi">acpi</a> -- advanced configuration and power interface<br> + <a href="#o_ide">ide</a> -- control the IDE subsystem<br> + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_splash">Kernel Options: splash</a></h3> + +The splash screen is the picture shown during system start-up.<br> +<br> +<em>splash=0</em><br> +The splash screen is switched off. This may be useful +with very old monitors or if some error occurs.<br> +<br> +<em>splash=verbose</em><br> Activates splash, kernel and boot messages are +still shown.<br> +<br> +<em>splash=silent</em><br> +Activates splash, but no messages. Instead a progress bar is drawn.<br> +<br> +Return to <a href="#opt">Boot Options</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_apm">Kernel Options: apm</a></h3> + +APM is one of the two power management strategies used on current +computers. It is mainly used with laptops for functions like suspend +to disk, but it may also be responsible for switching off the +computer after power down. APM relies on a correct working BIOS. If +the BIOS is broken, APM may have only limited use or even prevent the +computer from working. Therefore, it may be switched off with the +parameter<br><br> + + <em>apm=off</em> -- switch off APM completely<br><br> + +Some very new computers may benefit more from the newer +<a href="#o_acpi">ACPI</a>. + +<br><br>Return to <a href="#opt">Boot Options</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_acpi">Kernel Options: acpi</a></h3> + +ACPI (Advanced Configuration and Power Interface) is a +standard that defines power and configuration management interfaces +between an operating system and the BIOS. By default, <em>acpi</em> is +switched on when a BIOS is detected that is newer than from year +2000. There are several commonly +used parameters to control the behavior of ACPI:<br> +<br> + <em>pci=noacpi</em> -- do not use ACPI to route PCI interrupts + <em>acpi=oldboot</em> -- only the parts of ACPI that are relevant +for booting remain activated<br> + <em>acpi=off</em> -- switch off ACPI completely<br> + <em>acpi=force</em> -- switch on ACPI even if your BIOS is dated +before 2000<br> +<br> +Especially on new computers, it replaces the old +<a href="#o_apm">apm</a> system. + + +<br><br>Return to <a href="#opt">Boot Options</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_ide">Kernel Options: ide</a></h3> + +IDE is, unlike SCSI, commonly used in most desktop workstations. +To circumvent some hardware problems that occur with IDE systems, use the +kernel parameter: <br><br> + + <em>ide=nodma</em> -- switch off dma for IDE drives<br> + + + +<br><br>Return to <a href="#opt">Boot Options</a>. + +</body></html> diff --git a/themes/SuSE/help-boot.sk.html b/themes/SuSE/help-boot.sk.html new file mode 100644 index 0000000..56ba7c2 --- /dev/null +++ b/themes/SuSE/help-boot.sk.html @@ -0,0 +1,137 @@ +<html><body> + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="help">Použitie pomocníka</a></h3> + +Pomocník pre správcu štartu je kontextový. Poskytuje informácie +o vybranej položke menu alebo sa v prípade, že opravujete voľby +štartu, snaží o zobrazenie informácií o voľbe, na ktorej je +práve kurzor.<br> +<br> +Navigácia klávesnicou<br><br> + + <em>Šipka hore</em>: vybrať predchádzajúci odkaz<br> + <em>Šipka dolu</em>: vybrať nasledujúci odkaz<br> + <em>Šipka vľavo</em>, <em>Backspace</em>: návrat na prechádzajúci článok<br> + <em>Šipka vpravo</em>, <em>Enter</em>, <em>Space</em>: zobraziť odkaz<br> + <em>Page Up</em>: posunúť text o jednu stránku hore<br> + <em>Page Down</em>: posunúť text o jednu stránku dolu<br> + <em>Home</em>: prejsť na začiatok stránky<br> + <em>End</em>: prejsť na koniec stránky<br> + <em>Esc</em>: ukončiť pomocníka<br> + +<br>Návrat na <a href="#opt">Voľby štartu</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="startup">Výber režimu zobrazenia štartu</a></h3> + +<em>F2</em> umožňuje zmeniť režim zobrazenia počas štartu +systému. Ak chcete, môžete priamo použiť voľbu jadra <a href="#o_splash">splash</a>.<br> +<br> +<em>native</em> bude zobrazovať všetky správy jadra a štartu systému (rovnaké +ako splash=0)<br> +<br> +<em>silent</em> zabráni zobrazeniu všetkých správ od jadra +a štartu systému. Namiesto nich zobrazí pruh priebehu<br> +<br> +<em>verbose</em> zobrazí obrázok a správy jadra a štartu systému<br> + +<br>Návrat na <a href="#opt">Voľby štartu</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="keytable">Výber rozloženia klávesnice</a></h3> + +Stlačením <em>F9</em> sa zobrazí zoznam podporovaných +klávesníc.<br><br> + +Toto je experimentálna funkcia a nemusí fungovať správne. +(Preto nie je <em>F9</em> zobrazené.) + +<br><br>Návrat na <a href="#opt">Voľby štartu</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="opt">Voľby štartu</a></h3> + + <a href="#o_splash">splash</a> -- ovplyvňuje zobrazovanie informácií počas štartu<br> + <a href="#o_apm">apm</a> -- prepne správu napájania<br> + <a href="#o_acpi">acpi</a> -- pokročilé rozhranie nastavenia a správy napájania (Advanced Configuration and Power Interface)<br> + <a href="#o_ide">ide</a> -- ovládanie IDE systému<br> + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_splash">Voľby jadra: splash</a></h3> + +Splash je obrázok zobrazený pri štarte systému.<br> +<br> +<em>splash=0</em><br> +Obrázok je vypnutý. To sa môže hodiť na veľmi +starých monitoroch alebo v prípade, že sa vyskytne +nejaká chyba.<br> +<br> +<em>splash=verbose</em><br> Aktivuje obrázok, ale správy +o štarte jadra a systému sa budú zobrazovať.<br> +<br> +<em>splash=silent</em><br> +Aktivuje obrázok, ale bez správ. Namiesto nich sa zobrazí pruh +priebehu.<br> + +<br>Návrat na <a href="#opt">Voľby štartu</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_apm">Voľby jadra: apm</a></h3> + +APM je jedna z dvoch technológií pre správu napájania +pre súčasné počítače. Používa sa hlavne na prenosných +počítačoch na uspávanie, ale dokáže aj vypnúť počítač. +APM vyžaduje správne fungujúci BIOS. Ak je BIOS +nesprávny, APM môže fungovať iba čiastočne alebo dokonca +počítač môže prestať fungovať. V tom prípade budete možno +musieť APM vypnúť pomocou parametra<br><br> + + <em>apm=off</em> -- úplne vypnúť APM<br><br> + +Niektore nové počítač môžu využiť novšiu technológiu +<a href="#o_acpi">ACPI</a>. + +<br><br>Návrat na <a href="#opt">Voľby štartu</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_acpi">Voľby jadra: acpi</a></h3> + +ACPI (Advanced Configuration and Power Interface) je štandard, +ktorý definuje rozhrania pre správu napájania a nastavenia počítača +medzi BIOSom operačným systémom. Štandardne sa <em>acpi</em> +zapne, ak je BIOS novší než z roku 2000. Pre chovanie ACPI +existuje niekoľko často používaných parametrov:<br> +<br> + <em>pci=noacpi</em> -- nepoužívať ACPI pre správu prerušení PCI + <em>acpi=oldboot</em> -- aktivovať iba časti ACPI, ktoré sa týkajú + štartu systému<br> + <em>acpi=off</em> -- vypnúť ACPI úplne<br> + <em>acpi=force</em> -- zapnúť ACPI aj v prípade, že je BIOS starší + než z roku 2000<br> +<br> +Hlavne na nových počítačoch nahradzuje systém +<a href="#o_apm">apm</a>. + + +<br><br>Návrat na <a href="#opt">Voľby štartu</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_ide">Voľby jadra: ide</a></h3> + +IDE je rozhranie diskov často používané v pracovných staniciach. +Aby sa zabránilo niektorým problémom s IDE zariadeniami, použite +parameter jadra: <br><br> + + <em>ide=nodma</em> -- vypne DMA pre IDE zariadenia<br> + + +<br><br>Návrat na <a href="#opt">Voľby štartu</a> + +</body></html> diff --git a/themes/SuSE/help-install.en.html b/themes/SuSE/help-install.en.html new file mode 100644 index 0000000..836358e --- /dev/null +++ b/themes/SuSE/help-install.en.html @@ -0,0 +1,404 @@ +<html><body> + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="main">Boot Loader Help</a></h3> +Welcome to <em>SUSE LINUX 9.1</em><br><br> + +Use this menu to select the desired function. If you have +problems navigating in this help system, press +<em>F1</em> to enter the <a href="#help">description</a> of the help +system. The main functions in this menu are:<br><br> + +<a href="#harddisk">Boot from Hard Disk</a>: This selection will not do +anything to the system. It only starts a previously installed +operating system.<br><br> + +<a href="#linux">Installation</a>: +This installation mode works on most machines. If you experience a +system freeze during boot or problems with detection of your hardware +components, such as disk controllers or network cards, try one of the +following installation options. <br><br> + +<a href="#noacpi">Installation -- ACPI Disabled</a>: Many of the +currently-sold computers have incomplete or faulty ACPI +implementations. This selection disables ACPI support in the +kernel, but still enables many performance features, like DMA for IDE +hard disks. <br><br> + +<a href="#failsafe">Installation -- Safe Settings</a>: If you were not +successful with <em>Installation</em>, this selection might +solve the issue.<br><br> + +<a href="#manual">Manual Installation</a>: This item is intended for +experts. Use this +option to have the most possible control. Also use it to load extra modules, +for example, before starting the Rescue +System.<br><br> + +<a href="#rescue">Rescue System</a>: This boot image starts a small +Linux system in RAM. This is useful if the system does not start properly. +After booting this system, log in as root. <br><br> + +<a href="#memtest">Memory Test</a>: Memory testing is useful for more than +checking installation of new memory modules. It is a stress test +for a big part of your computer system and may indicate hardware +problems. <br><br> + +<a href="#opt">Boot Options</a>: The boot options may change the +behavior of your system completely. They are settings for +the kernel.<br><br> + +<a href="#help">F1 Help</a>: This is context sensitive. It will +show different screens depending on the active element of the +boot screen. There is also a description of this help system +available.<br><br> + +<a href="#videomode">F2 Video Mode</a>: Here, choose between +different screen resolutions while installing. If you encounter +problems with the graphical installation, the <em>text mode</em> may +be a work-around for you.<br><br> + +<a href="#install_src">F3 Installation Source</a>: Choose the +installation source.<br><br> + +<a href="#keytable">F4 Language</a>: Set language and keyboard mapping +used by the boot loader.<br><br> + +<a href="#startup">F5 Kernel Startup</a>: Normally, you won't see +any kernel messages. Use <em>F5</em> to change that.<br><br> + +<a href="#driverupdate">F6 Driver Update</a>: For very new machines, a +driver update may be needed to install the system.<br><br> + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="help">Using the Help System</a></h3> + +The boot loader online help is context sensitive. It gives information +about the selected menu item or, if you are editing boot options, +it tries to look up information about the option in which the cursor is +positioned.<br> +<br> +Navigation Keys<br><br> + + <em>Up Arrow</em>: highlight previous link<br> + <em>Down Arrow</em>: highlight next link<br> + <em>Left Arrow</em>, <em>Backspace</em>: return to previous topic<br> + <em>Right Arrow</em>, <em>Enter</em>, <em>Space</em>: follow link<br> + <em>Page Up</em>: scroll up one page<br> + <em>Page Down</em>: scroll down one page<br> + <em>Home</em>: go to page start<br> + <em>End</em>: go to page end<br> + <em>Esc</em>: leave help<br> + +<br><br>Return to <a href="#main">Start Page</a> + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="driverupdate">Driver Update</a></h3> + +If you need a driver update floppy or CD-ROM, press <em>F6</em>. The +boot loader asks you to insert the driver update medium after +loading the Linux kernel.<br><br> + +A driver update is typically a floppy with new versions of hardware +drivers or bug fixes needed during installation. + +<br><br>Return to <a href="#main">Start Page</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="videomode">Video Mode Selection</a></h3> + +Press <em>F2</em> to get the list of video modes your graphics card +supports. The highest mode your monitor can display is preselected.<br><br> + +It is possible that your monitor cannot be detected automatically. In that +case, select your preferred mode manually.<br><br> + +If your system has problems with the graphics card during the +installation, the <em>text mode</em> may be a usable work-around. + +<br><br>Return to <a href="#main">Start Page</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="startup">Splash Mode Selection</a></h3> + +<em>F5</em> lets you change the splash screen mode. You can +use the <a href="#o_splash">splash</a> kernel option directly, if you prefer.<br> +<br> +<em>native</em> turns the splash screen off (same as splash=0)<br> +<br> +<em>verbose</em> shows nice picture and kernel and boot messages<br> +<br> +<em>silent</em> suppresses all kernel and boot messages and shows a progress +bar instead<br> + +<br><br>Return to <a href="#main">Start Page</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="keytable">Language and Keyboard Layout Selection</a></h3> + +Press <em>F4</em> to change language and keyboard layout the boot loader uses. + +<br><br>Return to <a href="#main">Start Page</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="install_src">Installation Source</a></h3> + +Press <em>F3</em> to choose an installation source.<br><br> + +This is the same as using the <a href="#o_install">install</a> +boot option. + +<br><br>Return to <a href="#main">Start Page</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="linux">Installation</a></h3> + +Select <em>Installation</em> to start the default installation. The +<a href="#opt">boot options</a> entered are used in the +start-up. This item activates many features of commonly available +hardware. <br><br> + +<br><br>Return to <a href="#main">Start Page</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="harddisk">Boot from Hard Disk</a></h3> + +Select <em>Boot Installed OS</em> to start the system installed on +your local hard disk. This system must be installed properly, because +only the MBR (Master Boot Record) on the first hard disk is started. +The device ID of the first hard disk is provided by the BIOS of +the computer. <br><br> + +Use this if you forgot to remove the CD or DVD from your +drive and want to start the computer from the hard disk.<br><br> + +<br><br>Return to <a href="#main">Start Page</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="noacpi">Installation -- ACPI Disabled</a></h3> + +In SuSE Linux, the ACPI support of the developer kernel 2.5 is already +available for the stable 2.4 kernel. Very new hardware sometimes +requires ACPI to control the interrupt handling. ACPI completely +replaces the old APM system. <br><br> + +Select <em>Installation -- ACPI Disabled</em> if you encounter +problems during boot of the kernel. Known problems with machines that +have problems with ACPI are: +<br><br> + + * kernel freezes when booting<br> + * PCI Cards are not detected or initialized properly<br><br> + + +<br><br>Return to <a href="#main">Start Page</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="failsafe">Installation -- Safe Settings</a></h3> + +Select <em>Installation -- Safe Settings</em> if you encounter hangs +while installing or irreproducible errors. This option disables DMA +for IDE drives and all power management features. +See also the kernel options for <a href="#o_apm">apm</a>, +<a href="#o_acpi">acpi</a> and <a href="#o_ide">ide</a>. + +<br><br>Return to <a href="#main">Start Page</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="manual">Manual Installation</a></h3> + +<em>Manual Installation</em> enables the professional to tune several +installation parameters before installing a system or booting the +<a href="#rescue">Rescue System</a>. This is intended for expert use +only. + +<br><br>Return to <a href="#main">Start Page</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="rescue">Rescue System</a></h3> + +The <em>Rescue System</em> is a small RAM disk base system. From there, +it is possible to make all kinds of changes to an installed system. Because +only low-level tools are available in this system, it is intended for +experts.<br><br> + +<br><br>Return to <a href="#main">Start Page</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="memtest">Memory Test</a></h3> + +The included <em>Memory Test</em> provides good possibilities to +stress test the hardware of a system. Its main purpose is to detect +broken RAM, but it also stresses many other parts of the system. <br> + +There is no guarantee that the memory is good if no errors are +found, although most of memory defects will be found.<br> + +<br><br>Return to <a href="#main">Start Page</a> + + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="opt">Boot Options</a></h3> + +There are two types of boot options available. First, there are +options that affect the installer. Second, there are kernel +options. Some of the more common options are: <br><br> +a) installer options<br> +<br> + <a href="#o_install">install</a> -- select an installation source<br> + <a href="#network">network options</a> -- the network options<br> + <a href="#o_vnc">vnc options</a> -- options for installation via VNC +<br><br> +b) kernel options<br> +<br> + <a href="#o_splash">splash</a> -- influence the behavior of the splash screen<br> + <a href="#o_apm">apm</a> -- toggle power management<br> + <a href="#o_acpi">acpi</a> -- advanced configuration and power interface<br> + <a href="#o_ide">ide</a> -- control the IDE subsystem<br> + +<br><br>Return to <a href="#main">Start Page</a> + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_install">Installer Options: install</a></h3> + +By default, the local CD-ROMs are searched for the installation source. +For a network install, select the +<em>install</em> option. Possible installation protocols are<br> + * FTP<br> + * NFS<br> + * HTTP<br> +The syntax to use is just like standard URLs. For example, +if your server is found at 192.168.0.1 and you want to do an NFS-based +install from the directory /install on this server, specify +the source as follows:<br><br> + + <em>install=nfs://192.168.0.1/install</em><br><br> + +The network card will either be configured with <em>dhcp</em> or you +must specify the parameters yourself as described in the +<a href="#network">network options</a>.<br> + +<br><br>Return to <a href="#opt">Boot Options</a> + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_splash">Kernel Options: splash</a></h3> + + +The splash screen is the picture shown during system start-up.<br> +<br> +<em>splash=0</em><br><br> The splash screen is switched off. This may be useful +with very old monitors or if some error occurs.<br> +<br> +<em>splash=verbose</em><br><br> Activates splash, kernel and boot messages are +still shown.<br> +<br> +<em>splash=silent</em><br><br> +Activates splash, but no messages. Instead a progress bar is drawn.<br> +<br> +Return to <a href="#opt">Boot Options</a> + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="network">Installer Options: Network Options</a></h3> + +It is possible to configure the network interface right now. The +hardware will be detected later by YaST2. The minimum set of options +to configure your network card consists of host IP and netmask. For +example:<br><br> + + <em>hostip=192.168.0.10 netmask=255.255.255.0</em><br> +<br> +or in a shorter form:<br><br> + + <em>hostip=192.168.0.10/24</em><br> +<br> + +If you specified a <a href="#o_install">network-based install</a> and do +not specify both of these options, the installer tries to configure +the network interface with <em>dhcp</em>. If you need a default +gateway, specify this with the option <em>gateway</em>. For +example:<br><br> + + <em>gateway=192.168.0.8</em><br> + +<br><br>Return to <a href="#opt">Boot Options</a> + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_vnc">Installer Options: vnc</a></h3> + +To enable the VNC installation, specify the +parameters vnc and vncpassword:<br><br> + + <em>vnc=1 vncpassword=example</em><br><br> + +The VNC server will be started and you may control YaST2 over any VNC +client from a remote system.<br> + +<br><br>Return to <a href="#opt">Boot Options</a>. + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_apm">Kernel Options: apm</a></h3> + +APM is one of the two power management strategies used on current +computers. It is mainly used with laptops for functions like suspend +to disk, but it may also be responsible for switching off the +computer after power down. APM relies on a correct working BIOS. If +the BIOS is broken, APM may have only limited use or even prevent the +computer from working. Therefore, it may be switched off with the +parameter<br><br> + + <em>apm=off</em> -- switch off APM completely<br><br> + +Some very new computers may take more advantage from the newer +<a href="#o_acpi">ACPI</a>. + + +<br><br>Return to <a href="#opt">Boot Options</a> + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_acpi">Kernel Options: acpi</a></h3> + +ACPI (Advanced Configuration and Power Interface) is a +standard that defines power and configuration management interfaces +between an operating system and the BIOS. By default, <em>acpi</em> is +switched on when a BIOS is detected that is newer than from year +2000. There are several commonly +used parameters to control the behavior of ACPI:<br> +<br> + <em>pci=noacpi</em> -- do not use ACPI to route PCI interrupts + <em>acpi=oldboot</em> -- only the parts of ACPI that are relevant +for booting remain activated<br> + <em>acpi=off</em> -- switch off ACPI completely<br> + <em>acpi=force</em> -- switch on ACPI even if your BIOS is dated +before 2000<br> +<br> +Especially on new computers, it replaces the old +<a href="#o_apm">apm</a> system. + + +<br><br>Return to <a href="#opt">Boot Options</a> + +<hr><!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> +<h3><a name="o_ide">Kernel Options: ide</a></h3> + +IDE is, unlike SCSI, commonly used in most desktop workstations. +To circumvent some hardware problems that occur with IDE systems, use the +kernel parameter: <br><br> + + <em>ide=nodma</em> -- switch off DMA for IDE drives<br> + + + +<br><br>Return to <a href="#opt">Boot Options</a>. + +</body></html> diff --git a/themes/SuSE/help.inc b/themes/SuSE/help.inc new file mode 100644 index 0000000..fda1137 --- /dev/null +++ b/themes/SuSE/help.inc @@ -0,0 +1,697 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% help system +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +% global vars used by help system + + +/help.context "main" def + +/help.light white def +/help.dark black def +/help.font font.normal def +/help.normal.bg lightgray def +/help.normal.fg black def +/help.highlight.fg green def +/help.link.fg blue def +/help.link.selected.fg white def +/help.link.selected.bg blue def + +/help.x 80 def +/help.y 50 def +/help.width 480 def +/help.height 322 def + +/help.text.x help.x 10 add def +/help.text.y help.y 30 add def + +/help.text.width help.width 20 sub def +/help.text.height help.height help.text.y sub help.y add 4 sub def +/help.text.rightmargin help.text.x help.text.width add def + +/help.title.x help.x 10 add def +/help.title.y help.y 3 add def +/help.title.height 20 def +/help.title.font font.normal def + +% /help.title.bg 0x299dcd newcolor +% for dialogs, too +/title.bg 0x317db4 newcolor +% /title.bg 0x2d9e6b newcolor +% /title.bg 0x2c9f84 newcolor +% /title.bg 0x36b74e newcolor + +/help.hist.page 16 array def +/help.hist.startrow help.hist.page length array def +/help.hist.selectedlink help.hist.page length array def + + +% for boot option lookup +/bo.opt.max 32 def +/bo.opt bo.opt.max 3 add string def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Map help context. +% +% ( context ) ==> ( new_context ) +% +/help.mapcontext { + dup "o_vncpassword" eq { pop "o_vnc" } if + dup "o_hostip" eq { pop "network" } if + dup "o_netmask" eq { pop "network" } if + dup "o_gateway" eq { pop "network" } if + dup "o_pci" eq { pop "o_acpi" } if + + syslinux not { + % only help, startup, keytable and option pages + dup "o_" strstr 1 ne { + dup "help" ne + over "startup" ne and + over "keytable" ne and + over "profile" ne and { pop "opt" } if + } if + } if +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Set help context. +% +% ( context ) ==> ( ) +% +/help.setcontext { + help.mapcontext /help.context exch def +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Find boot option the cursor is positioned at. +% +% ( ) ==> ( option ) +% +/findbootoption { + /bo.buf boot.ed 3 get def + /bo.len boot.ed 4 get def + /bo.pos boot.ed 5 get def + + { + bo.pos 0 eq { exit } if + bo.buf bo.pos 1 sub get ' ' le { exit } if + /bo.pos bo.pos 1 sub def + } loop + + /bo.buf bo.buf bo.pos add def + + bo.buf 0 get ' ' le { "" return } if + + % "o_" + option name is the help text label + "o_" 3 bo.opt snprintf + + 0 1 bo.opt.max 1 sub { + dup + bo.buf exch get + dup ' ' le over '=' eq or { pop pop exit } if + over bo.opt 2 add exch rot put + bo.opt 3 add exch 0 put + } for + + bo.opt + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Find help page. +% +% returns help page or empty string if no page was found +% +% ( label ) ==> ( help_text ) +% +/help.findpage { + dup length 3 add dup string + "\x12%s\x14" + 3 1 roll dup 5 1 roll snprintf + help.getmessages over strstr + dup { help.getmessages exch 1 sub add } { pop "" } ifelse + exch free +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Find help page. +% +% returns n-th help page or empty string if no page was found +% +% ( n ) ==> ( help_text ) +% +/help.findpagebyindex { + help.getmessages exch + { + dup "\x04" strstr + dup { add } { pop pop "" exit } ifelse + } repeat +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Init & display help page. +% +% ( help_text start_row selected_link ) ==> ( ) +% +/help.initpage { + /help.selectedlink exch def + /help.startrow exch def + + /help.currenttext over def + + title.bg setcolor + help.x 1 add help.y 1 add moveto + help.width 2 sub help.title.height 1 sub fillrect + + help.text.x help.text.y moveto + currentmaxrows 0 setmaxrows exch formattext setmaxrows + + white setcolor + currenteotchar 16 seteotchar + help.title.x help.title.y moveto currenttitle + currentfont help.title.font setfont exch show setfont + seteotchar + + getlinks { help.selectedlink setlink } if + + help.updatepage + + % 500 0 moveto gettextrows print + % 400 0 moveto getlinks print + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Redraw help page. +% +% ( ) ==> ( ) +% +/help.updatepage { + help.normal.bg setcolor + help.text.x help.text.y moveto + help.text.width help.text.height fillrect + + help.normal.fg help.highlight.fg help.link.fg help.link.selected.fg settextcolors + + help.startrow setstartrow + + help.text.x help.text.y moveto + help.currenttext show + + 0 setstartrow + + true help.selectedlink help.redrawlink + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Used to iterate over all help pages (for debugging). +% +% get the n-th page starting from current pos +% +% ( n ) ==> ( help_text ) +% +/help.test { + help.test.cnt add + dup 1 lt { pop 1 } if + /help.test.cnt over def + help.findpagebyindex + dup "" eq { + % one page back + pop help.test.cnt 1 sub /help.test.cnt over def + help.findpagebyindex + } if +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Redraw link. +% +% selected: true or false. +% +% ( selected n ) ==> ( ) +% +% +/help.redrawlink { + getlinks 0 eq { pop pop return } if + getlink + dup help.startrow lt + over help.startrow help.text.rows add ge or { + 5 { pop } repeat return + } if + help.startrow sub lineheight mul help.text.y add + moveto + rot + + 16 seteotchar + + { + currenttextcolors 4 1 roll pop pop pop + help.link.selected.bg + } { + currenttextcolors 4 2 roll pop pop pop + help.normal.bg + } ifelse + + setcolor over currentpoint rot strsize fillrect moveto + + setcolor show + + 4 seteotchar + + pop +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Select n-th link. +% +% ( n ) ==> ( ) +% +/help.selectlink { + help.selectedlink over eq { + pop + } { + % deselect old link + false help.selectedlink help.redrawlink + + /help.selectedlink over dup setlink def + + % select link + true exch help.redrawlink + } ifelse +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Select first visible link. +% +% No screen update if 'update' is false. +% +% ( update ) ==> ( ) +% +/help.sel.firstlink { + getlinks { + 0 1 getlinks 1 sub { + dup + getlink 4 1 roll pop pop pop + dup help.startrow help.text.rows add ge { + pop pop exit + } if + dup help.startrow ge { + pop + over { help.selectlink } { /help.selectedlink exch dup setlink def } ifelse + exit + } if + pop pop + } for + } if + pop +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Select last visible link. +% +% No screen update if 'update' is false. +% +% ( update ) ==> ( ) +% +/help.sel.lastlink { + getlinks { + getlinks 1 sub -1 0 { + dup + getlink 4 1 roll pop pop pop + dup help.startrow lt { + pop pop exit + } if + dup help.startrow help.text.rows add lt { + pop + over { help.selectlink } { /help.selectedlink exch dup setlink def } ifelse + exit + } if + pop pop + } for + } if + pop +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Push current help context to history. +% +% ( ) ==> ( ) +% +/help.add2history { + help.hist.index help.hist.page length lt { + help.hist.page help.hist.index help.currenttext put + help.hist.startrow help.hist.index help.startrow put + help.hist.selectedlink help.hist.index help.selectedlink put + /help.hist.index help.hist.index 1 add def + } if +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Follow currently selected link. +% +% ( ) ==> ( ) +% +/help.followlink { + getlinks { + help.selectedlink getlink pop pop pop + help.add2history + help.findpage + dup "" eq { + pop + } { + 0 0 help.initpage + } ifelse + } if +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Go back to previous page. +% +% ( ) ==> ( ) +% +/help.prevlink { + help.hist.index 0 gt { + /help.hist.index help.hist.index 1 sub def + help.hist.page help.hist.index get + help.hist.startrow help.hist.index get + help.hist.selectedlink help.hist.index get + help.initpage + } if +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Scroll a page down. +% +% ( ) ==> ( ) +% +/help.key.pagedown { + help.startrow + gettextrows help.text.rows gt { + pop + gettextrows help.text.rows sub + help.startrow help.text.rows add + min + } if + + dup help.startrow eq { + pop + true help.sel.lastlink + } { + /help.startrow exch def + false help.sel.firstlink + help.updatepage + } ifelse +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Scroll a page up. +% +% ( ) ==> ( ) +% +/help.key.pageup { + help.startrow + gettextrows help.text.rows gt { + pop + 0 + help.startrow help.text.rows sub + max + } if + + dup help.startrow eq { + pop + true help.sel.firstlink + } { + /help.startrow exch def + false help.sel.firstlink + help.updatepage + } ifelse +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Go to page start. +% +% ( ) ==> ( ) +% +/help.key.home { + help.startrow 0 eq { + true help.sel.firstlink + } { + /help.startrow 0 def + false help.sel.firstlink + help.updatepage + } ifelse +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Go to page end. +% +% ( ) ==> ( ) +% +/help.key.end { + gettextrows help.text.rows sub 0 max + dup help.startrow eq { + pop + true help.sel.lastlink + } { + /help.startrow exch def + false help.sel.lastlink + help.updatepage + } ifelse +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Next link or scroll down. +% +% ( ) ==> ( ) +% +/help.key.down { + help.selectedlink getlinks 1 sub lt { + help.selectedlink 1 add getlink 4 1 roll pop pop pop + dup help.startrow help.text.rows add lt { + % link visible + pop help.selectedlink 1 add help.selectlink + return + } { + help.startrow help.text.rows add eq { + % link visible after scrolling down + /help.selectedlink help.selectedlink 1 add dup setlink def + } if + } ifelse + } if + + % scroll down + + help.startrow help.text.rows add gettextrows lt { + /help.startrow help.startrow 1 add def + help.updatepage + } if +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Previous link or scroll up. +% +% ( ) ==> ( ) +% +/help.key.up { + help.selectedlink 0 gt { + help.selectedlink 1 sub getlink 4 1 roll pop pop pop + % row + dup help.startrow ge { + % link visible + pop help.selectedlink 1 sub help.selectlink + return + } { + help.startrow 1 sub eq { + % link visible after scrolling up + /help.selectedlink help.selectedlink 1 sub dup setlink def + } if + } ifelse + } if + + % scroll up + + help.startrow 0 gt { + /help.startrow help.startrow 1 sub def + help.updatepage + } if +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Handle keyboard input. +% +% ( key_in ) ==> ( key_out ) +% +/help.input { + dup 0 eq { return } if + + dup keyEsc eq { /window.action actNothing def window.done } if + dup keyCtrlDown eq { 1 help.test 0 0 help.initpage } if + dup keyCtrlUp eq { -1 help.test 0 0 help.initpage } if + dup keyDown eq { help.key.down } if + dup keyUp eq { help.key.up } if + dup keyPgDown eq { help.key.pagedown } if + dup keyPgUp eq { help.key.pageup } if + dup keyHome eq { help.key.home } if + dup keyEnd eq { help.key.end } if + dup keyRight eq { help.followlink } if + dup keyEnter eq { help.followlink } if + dup 0xff and ' ' eq { help.followlink } if + dup keyLeft eq { help.prevlink } if + dup 0xff and '\x08' eq { help.prevlink } if + dup keyF1 eq { + "help" help.findpage + dup help.currenttext eq { + pop + } { + help.add2history + 0 0 help.initpage + } ifelse + } if +% dup keyF9 eq { +% /help.font help.font 8 add 10 mod def help.reinit +% help.currenttext help.startrow help.selectedlink help.initpage +% } if + pop 0 +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Recalculate some sizes and redraw help screen. +% +% ( ) ==> ( ) +% +/help.reinit { + help.normal.bg setcolor + help.x help.y moveto + help.width help.height fillrect + + help.x 1 add help.y 1 add help.title.height add moveto + help.dark help.light + help.width 2 sub help.height 2 sub help.title.height sub + drawborder + + help.font setfont + + /help.text.rows help.text.height lineheight div def + help.text.rows setmaxrows + + help.text.rightmargin settextwrap +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Initialize help window. +% +% ( window ) ==> ( ) +% +/help.init { + /help.tmp exch def + + help.x 1 sub help.y 1 sub moveto + help.light help.dark + help.width 2 add help.height 2 add + over over + + % just for testing: lilo has enough low memory + lilo { savescreen } { xsavescreen } ifelse + + help.tmp .saved rot put + drawborder + + help.reinit + + 4 seteotchar + + /help.hist.index 0 def + + /help.test.cnt 1 def + + help.context help.findpage 0 0 help.initpage +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Draw help window. +% +% ( window ) ==> ( ) +% +/help.show { + window.push +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Close current help window. +% +% ( ) ==> ( ) +% +/help.done { + 0 settextwrap + 0 seteotchar + 0 setmaxrows +} def + + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Create new help window. +% +% ( ) ==> ( window ) +% +/window.help { + widget.size array + dup .type t_help put + + dup .x help.x put + dup .y help.y put + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Find help texts. +% +% ( ) ==> ( start_of_help_messages ) +% +/help.getmessages { + + help.messages .undef eq { + % find help texts + /help.messages + 16 string dup config.lang "help.%s" 2 index sprintf + findfile exch free + dup .undef eq { pop "help.en" findfile } if + dup .undef eq { pop "" } if + cvs + def + } if + + help.messages + +} def + + diff --git a/themes/SuSE/install.config b/themes/SuSE/install.config new file mode 100644 index 0000000..6824e0a --- /dev/null +++ b/themes/SuSE/install.config @@ -0,0 +1,24 @@ +%% include system.inc +%% include bsplash.inc + +%% include common.inc + + +%% include po/text.inc +%% include window.inc +%% include button.inc +%% include help.inc +%% include main.inc +%% include xmenu.inc +%% include dia_video.inc +%% include dia_splash.inc +%% include dia_lang.inc +%% include dia_dud.inc +%% include dia_help.inc +%% include dia_profile.inc +%% include dia_install.inc +%% include panel.inc +%% include keytables.inc +%% include locale.inc + + diff --git a/themes/SuSE/keytables.inc b/themes/SuSE/keytables.inc new file mode 100644 index 0000000..a69ef31 --- /dev/null +++ b/themes/SuSE/keytables.inc @@ -0,0 +1,263 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% Keyboard mappings. +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% keymap layout (diff to us map): +% +% key_code, plain, shift, altgr +% + +/keymap.cs [ + [ 0x02 0x2b 0x31 0x00 ] + [ 0x03 0x11b 0x32 0x00 ] + [ 0x04 0x161 0x33 0x00 ] + [ 0x05 0x10d 0x34 0x00 ] + [ 0x06 0x159 0x35 0x00 ] + [ 0x07 0x17e 0x36 0x00 ] + [ 0x08 0xfd 0x37 0x00 ] + [ 0x09 0xe1 0x38 0x00 ] + [ 0x0a 0xed 0x39 0x00 ] + [ 0x0b 0xe9 0x30 0x00 ] + [ 0x0c 0x3d 0x25 0x2d ] + [ 0x0d 0x00 0x00 0x3d ] + [ 0x15 0x7a 0x5a 0x79 ] + [ 0x1a 0xfa 0x2f 0x5b ] + [ 0x1b 0x29 0x28 0x5d ] + [ 0x27 0x16f 0x22 0x3b ] + [ 0x28 0xa7 0x21 0x27 ] + [ 0x29 0x60 0x3b 0x00 ] + [ 0x2c 0x79 0x59 0x7a ] + [ 0x2e 0x63 0x43 0x00 ] + [ 0x33 0x2c 0x3f 0x00 ] + [ 0x34 0x2e 0x3a 0x00 ] + [ 0x35 0x2d 0x5f 0x2f ] + [ 0x56 0x7c 0x00 0x3c ] +] def + + +/keymap.de [ + [ 0x03 0x32 0x22 0xb2 ] + [ 0x04 0x33 0xa7 0xb3 ] + [ 0x06 0x35 0x25 0x00 ] + [ 0x07 0x36 0x26 0x00 ] + [ 0x08 0x37 0x2f 0x7b ] + [ 0x09 0x38 0x28 0x5b ] + [ 0x0a 0x39 0x29 0x5d ] + [ 0x0b 0x30 0x3d 0x7d ] + [ 0x0c 0xdf 0x3f 0x5c ] + [ 0x0d 0x27 0x60 0x00 ] + [ 0x10 0x71 0x51 0x40 ] + [ 0x12 0x65 0x45 0x20ac ] + [ 0x15 0x7a 0x5a 0x00 ] + [ 0x1a 0xfc 0xdc 0x00 ] + [ 0x1b 0x2b 0x2a 0x7e ] + [ 0x27 0xf6 0xd6 0x00 ] + [ 0x28 0xe4 0xc4 0x00 ] + [ 0x29 0x5e 0xb0 0x00 ] + [ 0x2b 0x23 0x27 0x00 ] + [ 0x2c 0x79 0x59 0x00 ] + [ 0x32 0x6d 0x4d 0xb5 ] + [ 0x33 0x2c 0x3b 0x00 ] + [ 0x34 0x2e 0x3a 0x00 ] + [ 0x35 0x2d 0x5f 0x00 ] + [ 0x56 0x3c 0x3e 0x7c ] +] def + + +/keymap.es [ + [ 0x02 0x31 0x21 0x7c ] + [ 0x03 0x32 0x22 0x40 ] + [ 0x04 0x33 0xb7 0x23 ] + [ 0x05 0x34 0x24 0x7e ] + [ 0x06 0x35 0x25 0x00 ] + [ 0x07 0x36 0x26 0xac ] + [ 0x08 0x37 0x2f 0x7b ] + [ 0x09 0x38 0x28 0x5b ] + [ 0x0a 0x39 0x29 0x5d ] + [ 0x0b 0x30 0x3d 0x7d ] + [ 0x0c 0x27 0x3f 0x5c ] + [ 0x0d 0xa1 0xbf 0x7e ] + [ 0x1a 0x00 0x00 0x5b ] + [ 0x1b 0x2b 0x2a 0x5d ] + [ 0x27 0xf1 0xd1 0x00 ] + [ 0x28 0x00 0x00 0x7b ] + [ 0x29 0xba 0xaa 0x5c ] + [ 0x2b 0xe7 0xc7 0x7d ] + [ 0x2e 0x63 0x43 0x00 ] + [ 0x33 0x2c 0x3b 0x00 ] + [ 0x34 0x2e 0x3a 0x00 ] + [ 0x35 0x2d 0x5f 0x00 ] + [ 0x56 0x3c 0x3e 0x00 ] +] def + + +/keymap.fr [ + [ 0x02 0x26 0x31 0x00 ] + [ 0x03 0x7b 0x32 0x7e ] + [ 0x04 0x22 0x33 0x23 ] + [ 0x05 0x27 0x34 0x7b ] + [ 0x06 0x28 0x35 0x5b ] + [ 0x07 0x2d 0x36 0x7c ] + [ 0x08 0x7d 0x37 0x60 ] + [ 0x09 0x5f 0x38 0x5c ] + [ 0x0a 0x2f 0x39 0x5e ] + [ 0x0b 0x40 0x30 0x00 ] + [ 0x0c 0x29 0x5d 0x00 ] + [ 0x0d 0x3d 0x2b 0x7d ] + [ 0x10 0x61 0x41 0x00 ] + [ 0x11 0x7a 0x5a 0x00 ] + [ 0x1a 0x5e 0x3c 0x00 ] + [ 0x1b 0x24 0x3e 0x7e ] + [ 0x1e 0x71 0x51 0x00 ] + [ 0x27 0x6d 0x4d 0x00 ] + [ 0x28 0x7c 0x25 0x00 ] + [ 0x29 0x2a 0x7e 0x00 ] + [ 0x2b 0x2a 0x23 0x00 ] + [ 0x2c 0x77 0x57 0x00 ] + [ 0x2e 0x63 0x43 0x00 ] + [ 0x32 0x2c 0x3f 0x00 ] + [ 0x33 0x3b 0x2e 0x00 ] + [ 0x34 0x3a 0x2f 0x00 ] + [ 0x35 0x21 0x5c 0x00 ] + [ 0x56 0x3c 0x3e 0x7c ] +] def + + +/keymap.it [ + [ 0x03 0x32 0x22 0x00 ] + [ 0x04 0x33 0xa3 0x00 ] + [ 0x06 0x35 0x25 0x00 ] + [ 0x07 0x36 0x26 0x00 ] + [ 0x08 0x37 0x2f 0x00 ] + [ 0x09 0x38 0x28 0x7b ] + [ 0x0a 0x39 0x29 0x7d ] + [ 0x0b 0x30 0x3d 0x7e ] + [ 0x0c 0x27 0x3f 0x60 ] + [ 0x0d 0xec 0x5e 0xed ] + [ 0x1a 0xe8 0xe9 0x5b ] + [ 0x1b 0x2b 0x2a 0x5d ] + [ 0x27 0xf2 0xe7 0x40 ] + [ 0x28 0xe0 0xb0 0x23 ] + [ 0x29 0x5c 0x7c 0x00 ] + [ 0x2b 0xf9 0xa7 0xfa ] + [ 0x2e 0x63 0x43 0x00 ] + [ 0x33 0x2c 0x3b 0x00 ] + [ 0x34 0x2e 0x3a 0x00 ] + [ 0x35 0x2d 0x5f 0x00 ] + [ 0x56 0x3c 0x3e 0x00 ] +] def + + +/keymap.jp [ + [ 0x03 0x32 0x22 0x00 ] + [ 0x06 0x35 0x25 0x00 ] + [ 0x07 0x36 0x26 0x00 ] + [ 0x08 0x37 0x27 0x00 ] + [ 0x09 0x38 0x28 0x00 ] + [ 0x0a 0x39 0x29 0x00 ] + [ 0x0b 0x30 0x7e 0x00 ] + [ 0x0c 0x2d 0x3d 0x00 ] + [ 0x0d 0x5e 0x7e 0x00 ] + [ 0x1a 0x40 0x60 0x00 ] + [ 0x1b 0x5b 0x7b 0x00 ] + [ 0x27 0x3b 0x2b 0x00 ] + [ 0x28 0x3a 0x2a 0x00 ] + [ 0x29 0x1b 0x1b 0x00 ] + [ 0x2b 0x5d 0x7d 0x00 ] + [ 0x2e 0x63 0x43 0x00 ] + [ 0x56 0x3c 0x3e 0x00 ] + [ 0x59 0x5c 0x5f 0x00 ] + [ 0x5c 0x20 0x20 0x00 ] + [ 0x5e 0x20 0x20 0x00 ] + [ 0x7c 0x5c 0x7c 0x00 ] +] def + +/keymap.ru [ + [ 0x06 0x35 0x25 0x00 ] + [ 0x08 0x37 0x26 0x00 ] + [ 0x09 0x38 0x2a 0x00 ] + [ 0x0a 0x39 0x28 0x00 ] + [ 0x0b 0x30 0x29 0x00 ] + [ 0x0c 0x2d 0x5f 0x00 ] + [ 0x0f 0x09 0x09 0x00 ] + [ 0x10 0x71 0x51 0x439 ] + [ 0x11 0x77 0x57 0x446 ] + [ 0x12 0x65 0x45 0x443 ] + [ 0x13 0x72 0x52 0x43a ] + [ 0x14 0x74 0x54 0x435 ] + [ 0x15 0x79 0x59 0x43d ] + [ 0x16 0x75 0x55 0x433 ] + [ 0x17 0x69 0x49 0x448 ] + [ 0x18 0x6f 0x4f 0x449 ] + [ 0x19 0x70 0x50 0x437 ] + [ 0x1a 0x5b 0x7b 0x445 ] + [ 0x1b 0x5d 0x7d 0x5b ] + [ 0x1e 0x61 0x41 0x444 ] + [ 0x1f 0x73 0x53 0x44b ] + [ 0x20 0x64 0x44 0x432 ] + [ 0x21 0x66 0x46 0x430 ] + [ 0x22 0x67 0x47 0x43f ] + [ 0x23 0x68 0x48 0x440 ] + [ 0x24 0x6a 0x4a 0x43e ] + [ 0x25 0x6b 0x4b 0x43b ] + [ 0x26 0x6c 0x4c 0x434 ] + [ 0x27 0x3b 0x3a 0x436 ] + [ 0x28 0x27 0x22 0x44d ] + [ 0x2c 0x7a 0x5a 0x44f ] + [ 0x2d 0x78 0x58 0x447 ] + [ 0x2e 0x63 0x43 0x441 ] + [ 0x2f 0x76 0x56 0x43c ] + [ 0x30 0x62 0x42 0x438 ] + [ 0x31 0x6e 0x4e 0x442 ] + [ 0x32 0x6d 0x4d 0x44c ] + [ 0x33 0x2c 0x3c 0x431 ] + [ 0x34 0x2e 0x3e 0x44e ] + [ 0x56 0x3c 0x3e 0x7c ] +] def + + +/keymap.sk [ + [ 0x02 0x31 0x21 0x2b ] + [ 0x03 0x32 0x40 0x13e ] + [ 0x04 0x33 0x23 0x161 ] + [ 0x05 0x34 0x24 0x10d ] + [ 0x06 0x35 0x25 0x165 ] + [ 0x07 0x36 0x5e 0x17e ] + [ 0x08 0x37 0x26 0xfd ] + [ 0x09 0x38 0x2a 0xe1 ] + [ 0x0a 0x39 0x28 0xed ] + [ 0x0b 0x30 0x29 0xe9 ] + [ 0x0c 0x2d 0x5f 0x3d ] + [ 0x15 0x7a 0x5a 0x00 ] + [ 0x1a 0x5b 0x7b 0xfa ] + [ 0x1b 0x5d 0x7d 0xe4 ] + [ 0x27 0x3b 0x3a 0xf4 ] + [ 0x28 0x27 0x22 0xa7 ] + [ 0x2b 0x5c 0x7c 0x148 ] + [ 0x2c 0x79 0x59 0x00 ] + [ 0x2e 0x63 0x43 0x00 ] + [ 0x35 0x2f 0x3f 0x2d ] + [ 0x56 0x3c 0x3e 0x7c ] +] def + + +% must not be empty +/keymaps [ + [ "cs" "\u010ce\u0161tina" keymap.cs ] + [ "en" "English" .undef ] + [ "fr" "Fran\u00e7ais" keymap.fr ] + [ "de" "Deutsch" keymap.de ] + [ "it" "Italiano" keymap.it ] + [ "jp" "\u65e5\u672c\u8a9e" keymap.jp ] + [ "ru" "\u0420\u0443\u0441\u0441\u043a\u0438\u0439" keymap.ru ] + [ "sk" "Sloven\u010dina" keymap.sk ] + [ "es" "Espa\u00f1ol" keymap.es ] +] def + +% default entry +/keymaps.default 1 def + + diff --git a/themes/SuSE/kroete.data b/themes/SuSE/kroete.data Binary files differnew file mode 100644 index 0000000..448764b --- /dev/null +++ b/themes/SuSE/kroete.data diff --git a/themes/SuSE/locale.inc b/themes/SuSE/locale.inc new file mode 100644 index 0000000..d56d8a2 --- /dev/null +++ b/themes/SuSE/locale.inc @@ -0,0 +1,62 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% Handle translations. +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Set language. +% +% ( language ) ==> ( true|false ) +% +/setlang { + config.lang over eq { pop false return } if + + /config.lang exch def + + /help.messages .undef def + + findtexts + + true +} def + + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Find texts for current language. +% +% ( ) ==> ( ) +% +/findtexts { + 16 string dup config.lang "texts.%s" 2 index sprintf findfile exch free + dup .undef eq { + config.lang length 2 gt { + pop 16 string + dup config.lang 1 get config.lang 0 get "texts.%c%c" 3 index sprintf findfile exch free + dup { + /config.lang 2 string + config.lang 1 get config.lang 0 get "%c%c" 3 index sprintf + def + } if + } if + } if + dup .undef eq { pop "texts.en" findfile } if + dup .undef eq { pop 0 cvp } if + cvs + /ft.len over cvp length def + /ft.str exch def + /ft.pos 0 def + + texts { + ft.pos ft.str length add ft.len lt { + ft.str def + /ft.str ft.str dup length 1 add /ft.pos over ft.pos add def add def + } { + "No Texts!" def + } ifelse + } forall +} def + + diff --git a/themes/SuSE/main.inc b/themes/SuSE/main.inc new file mode 100644 index 0000000..3c0adfe --- /dev/null +++ b/themes/SuSE/main.inc @@ -0,0 +1,221 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% Main menu (boot entry + boot options + panel). +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Create new main window. +% +% ( ) ==> ( window ) +% +/window.main { + widget.size array + dup .type t_main put + dup .font font.normal put + dup .ed.font font.normal put + dup .color.fg boot.text.normal put + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Initialize main window. +% +% ( window ) ==> ( ) +% +/main.init { + pop +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Redraw main window. +% (E.g. after selecting a new language.) +% +% ( window ) ==> ( ) +% +/main.redraw { + boot.text.options setcolor + window.current .font get setfont + frame3.pos moveto + currentpoint 200 fontheight image + txt_bootoptions show + + redrawmenu + /keepbootoptions 1 def + menu.entry true MenuSelect + /keepbootoptions .undef def + + panel.show +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Draw main window. +% +% ( window ) ==> ( ) +% +/main.show { + window.push + + /menu.shift 0 def + /menu.visible.entries menu.texts length menu.max.entries min def + + % get index of default entry + /menu.entry 0 def + 0 1 menu.texts length 1 sub { + dup menu.texts exch get menu.dentry eq { /menu.entry exch def exit } { pop } ifelse + } for + + menu.entry menu.visible.entries sub 0 ge { + /menu.shift menu.entry menu.texts length menu.visible.entries sub min def + } if + + frame2.pos moveto prog_frame_color dup prog_frame_color2 frame2.size drawborder3 + + menu.visible.entries menu.texts length lt menu.scrollbar and { + /menu.bar.width frame1.size pop frame4.size pop sub def + + -1 settransparentcolor + + frame4.pos moveto black dup frame4.size drawborder + frame4.pos moveto + ms.up ms.size image + frame4.pos moveto frame4.size exch pop 0 exch ms.size exch pop 0 add sub rmoveto + ms.down ms.size image + + /menu.sb.x frame4.pos pop 1 add def + /menu.sb.y frame4.pos exch pop 22 add def + /menu.sb.width frame4.size pop 2 sub def + /menu.sb.height frame4.size exch pop 22 2 mul sub def + + menu.sb.x menu.sb.y 1 sub moveto + menu.sb.x menu.sb.width add menu.sb.y 1 sub lineto + + menu.sb.x menu.sb.y menu.sb.height add moveto + menu.sb.x menu.sb.width add menu.sb.y menu.sb.height add lineto + } if + + boot.text.options setcolor + + window.current .font get setfont + + frame3.pos moveto + txt_bootoptions show + + /boot.ed.width frame2.size pop 10 sub def + /boot.ed.height fontheight 2 add def + + /boot.ed [ + frame2.pos exch 5 add exch 4 add + over over moveto boot.ed.width boot.ed.height savescreen + boot.buf + boot.buf.size + 0 + 0 + 0 + ] def + + window.current .ed boot.ed put + + redrawmenu + menu.entry true MenuSelect + + % find default splash mode + 0 1 splash.options length 1 sub { + splash.options over get menu.args menu.entry get exch strstr { + /splash.default exch def + } { + pop + } ifelse + } for + + panel.init + + "main" help.setcontext + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Handle keyboard input. +% +% ( key_in ) ==> ( key_out ) +% +/main.input { + dup 0 eq { return } if + + % handle panel entries + panel.input + + dup keyF10 eq { + power_off + pop 0 + } if + + dup keyEsc eq { exit_popup pop 0 } if + + dup keyEnter eq { + /window.action actStart def + pop 0 + } if + + dup keyUp eq { + menu.entry 0 gt { + menu.entry false MenuSelect + menu.entry menu.shift eq { + /menu.shift menu.shift 1 sub def redrawmenu + } if + /menu.entry menu.entry 1 sub def + menu.entry true MenuSelect + } if + pop 0 + } if + + dup keyDown eq { + menu.entry menu.texts length 1 sub lt { + menu.entry false MenuSelect + menu.visible.entries menu.entry menu.shift sub sub 1 eq { + /menu.shift menu.shift 1 add def redrawmenu + } if + /menu.entry menu.entry 1 add def + menu.entry true MenuSelect + } if + pop 0 + } if + + dup keyPgUp eq { + menu.entry 0 gt { + menu.entry false MenuSelect + /menu.entry 0 def + menu.shift 0 ne { + /menu.shift 0 def redrawmenu + } if + menu.entry true MenuSelect + } if + pop 0 + } if + + dup keyPgDown eq { + menu.entry menu.texts length 1 sub lt { + menu.entry false MenuSelect + /menu.entry menu.texts length 1 sub def + menu.texts length menu.visible.entries sub dup menu.shift ne { + /menu.shift exch def redrawmenu + } { + pop + } ifelse + menu.entry true MenuSelect + } if + pop 0 + } if + + dup 0 ne { + "opt" help.setcontext + } if + +} def + + diff --git a/themes/SuSE/panel.inc b/themes/SuSE/panel.inc new file mode 100644 index 0000000..d952353 --- /dev/null +++ b/themes/SuSE/panel.inc @@ -0,0 +1,120 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% Panel handling. +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Some global vars. +% +/panel.text.y 461 def +/panel.font font.normal def +/panel.normal black def +/panel.high fn_color def +/panel.bg lightgray def +/panel.border white def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Init panel. +% +% ( ) ==> ( ) +% +/panel.init { + + % define panel layout + /panel [ + + % [ key x label show_func width_func update_func init_func ] + + [ keyF1 0 "F1" /panel.help /panel.help.width /panel.help.update .undef ] + + syslinux { + + [ keyF2 0 "F2" /panel.video /panel.video.width /panel.video.update /video.init ] + [ keyF3 0 "F3" /panel.install /panel.install.width /panel.install.update /install.init ] + [ keyF4 0 "F4" /panel.keytable /panel.keytable.width /panel.keytable.update /keytable.init ] + [ keyF5 0 "F5" /panel.splash /panel.splash.width /panel.splash.update /splash.init ] + [ keyF6 0 "F6" /panel.dud /panel.dud.width /panel.dud.update .undef ] + + } { + + [ keyF2 0 "F2" /panel.keytable /panel.keytable.width /panel.keytable.update /keytable.init ] + [ keyF3 0 "F3" /panel.splash /panel.splash.width /panel.splash.update /splash.init ] + "profiles" findfile dup { + /profile.data exch def + [ keyF4 0 "F4" /panel.profile /panel.profile.width /panel.profile.update /profile.init ] + } { pop } ifelse + + } ifelse + + ] def + + % initialize all + panel { 6 get dup .undef ne { exec } { pop } ifelse } forall + + panel.show +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Show panel. +% +% ( ) ==> ( ) +% +/panel.show { + panel.font setfont + + panel.bg setcolor + 0 panel.text.y 5 sub moveto currentpoint + clip.size panel.text.y 5 sub sub fillrect + moveto + panel.border setcolor + currentpoint exch pop clip.size pop 1 sub exch + lineto + + % don't change xmenu + /xmenu xmenu + + /panel.x 0 def + panel { dup { + dup 1 panel.x put + dup 4 get exec over 2 get strsize pop add 20 add panel.x add /panel.x exch def + dup 5 get exec + } { pop } ifelse } forall + + def + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Handle keyboard input. +% +% ( key_in ) ==> ( key_out ) +% +/panel.input { + panel { dup { + dup 0 get 2 index eq { 3 get exec pop 0 exit } { pop } ifelse + } { pop } ifelse } forall +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Draw panel entry label and move to text field. +% +% ( panel ) => ( ) +% +/panel.text.moveto { + /panel.tmp.x over 1 get 10 add def + /panel.tmp.F exch 2 get def + + panel.tmp.x panel.text.y moveto + panel.high setcolor panel.tmp.F show + panel.normal setcolor + + 6 0 rmoveto +} def + + diff --git a/themes/SuSE/po/Makefile b/themes/SuSE/po/Makefile new file mode 100644 index 0000000..d0f0914 --- /dev/null +++ b/themes/SuSE/po/Makefile @@ -0,0 +1,14 @@ +POFILES = $(wildcard *.po) +TEXTS = $(addprefix texts.,$(basename $(wildcard *.po))) + +all: text.inc $(TEXTS) + +texts.%: %.po text.inc + bin/po2txt $< >$@ + +# texts.en uses msgids from bootloader.pot +texts.en text.inc: bootloader.pot + bin/po2txt $< >texts.en + +clean: + rm -f text.inc texts.* *~ diff --git a/themes/SuSE/po/README b/themes/SuSE/po/README new file mode 100644 index 0000000..a27800a --- /dev/null +++ b/themes/SuSE/po/README @@ -0,0 +1,24 @@ +boot loader translations +------------------------ + +o How do I add a new text? + + - Use the gfxboot/po/bin/add_text script; example: + + add_text help 'Help' + + This will define txt_help; the 'txt_' prefix is optional. + +o How do I remove a text that's no longer needed? + + - Use the gfxboot/po/bin/rm_text script; example: + + rm_text help + + This will remove txt_help; the removed lines are stored in the 'old' + directory. + +o How do I add a new language? + + - Copy bootloader.pot to <lang>.po. Remember to get <lang>.po translated. + diff --git a/themes/SuSE/po/bin/add_text b/themes/SuSE/po/bin/add_text new file mode 100755 index 0000000..0dd99b1 --- /dev/null +++ b/themes/SuSE/po/bin/add_text @@ -0,0 +1,54 @@ +#! /usr/bin/perl + +# add a new text to *.po files + +die "usage: add_text [-c comment] id text_line1 text_line2 ... \nexample:\n add_text MENU_LANG Language\n" if @ARGV < 2; + +if($ARGV[0] eq '-c') { + shift; + $comment = shift; +} + +$id = shift; +@texts = @ARGV; + +$id =~ s/^txt_//; + +$_ = join '', @texts; + +push @l, "# $comment\n" if $comment; +push @l, "#. txt_$id\n"; +push @l, "#, c-format\n" if /%/; + +if(@texts == 1) { + push @l, "msgid \"$texts[0]\"\n" +} +else { + push @l, "msgid \"\"\n"; + for (@texts) { push @l, "\"$_\"\n" } +} + +push @l, "msgstr \"\"\n"; +push @l, "\n"; + +print @l; + +print STDERR "Should this entry be added to all *.po files? [Y/n]\n"; + +$_ = <STDIN>; + +chomp; + +$_ = "\L$_"; + +exit unless $_ eq '' || $_ eq 'y'; + +print "ok\n"; + +for $f ("bootloader.pot", <*.po>) { + if(open F, ">>$f") { + print F @l; + close F; + } +} + diff --git a/themes/SuSE/po/bin/po2txt b/themes/SuSE/po/bin/po2txt new file mode 100755 index 0000000..1003cae --- /dev/null +++ b/themes/SuSE/po/bin/po2txt @@ -0,0 +1,154 @@ +#! /usr/bin/perl + +# convert *.po files to texts.* files suitable for gfxboot +# usage: po2txt lang.po >texts.lang +# Note: en.po ist treated specially! + +sub read_texts; +sub join_msg; + +for $lang (@ARGV) { + $lang = 'en' if $lang eq 'bootloader.pot'; + $lang =~ s/\.po$//; + read_texts $lang; +} + + +sub read_texts +{ + local $_; + + my ($lang, @f, $txt, $context, $t, $p, $ids, $file); + + $lang = shift; + + $file = "$lang.po"; + $file = 'bootloader.pot' if $lang eq 'en'; + + if($lang eq 'en') { + $ids = 1; + } + + open F, $file; + @f = (<F>); + close F; + + $_ = $lang; + s/.*\///; + + for (@f) { + if(/^\s*#\.\s*(txt_\S+)/) { + if($txt) { + @msgstr = @msgid if $ids || join_msg(\@msgstr) eq ""; + $txts{$txt} = join_msg(\@msgstr); + } + + $txt = $1; + + undef @msgid; + undef @msgstr; + undef $context; + next; + } + + next if /^\s*#.*|^\s*$/; + + if(/^\s*msgid\s*(\".*\")\s*$/) { + push @msgid, $1 unless $1 eq '""'; + $context = 1; + next; + } + + if(/^\s*msgstr\s*(\".*\")\s*$/) { + push @msgstr, $1 unless $1 eq '""'; + $context = 2; + next; + } + + if(/^\s*(\".*\")\s*$/) { + if($context == 1) { + push @msgid, $1; + } + elsif($context == 2) { + push @msgstr, $1; + } + else { + die "format oops in ${lang}.po: $_" + } + } + } + + if($txt) { + @msgstr = @msgid if $ids || join_msg(\@msgstr) eq ""; + $txts{$txt} = join_msg(\@msgstr); + } + + @txts = sort keys %txts; + + for (@txts) { + $txt = $txts{$_}; + $txt =~ s/\\\\/\\/g; + $txt =~ s/\\n/\n/g; + print "$txt\x00" + } + + if($ids) { + open W, ">text.inc"; + print W "%\n% This file is generated automatically. Editing it is pointless.\n%\n\n"; + print W "/texts [\n"; + $p = pop @txts; + for (@txts) { print W " /$_\n" } + print W " /$p\n] def\n"; + close W; + } + else { + open F, "text.inc"; + for (<F>) { + if(/\s+\/(txt_\S+)/) { + $txt_ref{$1} = undef; + } + } + close F; + for (@txts) { + $txt_list{$_}++; + $txt_multi{$_} = 1 if $txt_list{$_} > 1; + } + for (@txts) { + $txt_unknown{$_} = 1 unless exists $txt_ref{$_}; + } + for (keys %txt_ref) { + $txt_miss{$_} = 1 unless exists $txt_list{$_}; + } + + if(defined(%txt_miss) || defined(%txt_unknown) || defined(%txt_multi)) { + print STDERR "$lang:\n"; + for (sort keys %txt_miss) { + print STDERR " missing: $_\n" + } + for (sort keys %txt_unknown) { + print STDERR " unknown: $_\n" + } + for (sort keys %txt_multi) { + print STDERR " multi: $_\n" + } + } + } + +} + + +sub join_msg +{ + local $_; + my ($s, $msg, $m); + + $msg = shift; + + for $s (@{$msg}) { + $_ = $s; + s/^\"(.*)\"$/$1/; + $m .= $_; + } + + return $m; +} diff --git a/themes/SuSE/po/bin/rm_text b/themes/SuSE/po/bin/rm_text new file mode 100755 index 0000000..9b96555 --- /dev/null +++ b/themes/SuSE/po/bin/rm_text @@ -0,0 +1,63 @@ +#! /usr/bin/perl + +# remove a text from *.po files + +sub drop; + +die "usage: rm_text id\n" if @ARGV != 1; + +$id = shift; +$id = "txt_$id" unless $id =~ /^txt_/; + +mkdir old, 0755; + +for $f ("bootloader.pot", <*.po>) { + if(open F, $f) { + @f = <F>; + close F; + + ( $new, $old ) = drop @f; + if(open F, ">>old/$f") { + print F @$old; + close F; + + open F, ">$f"; + print F @$new; + close F; + } + } +} + + +sub drop +{ + local $_; + my (@f, @g, $drop_it, @d); + + for (@_) { + push @g, $_; + $drop_it = 1 if /^#\.\s*${id}\s*$/; + if(/^\s*$/) { + if($drop_it) { + push @d, @g; + } + else { + push @f, @g; + } + undef $drop_it; + undef @g; + } + } + + if(@g) { + if($drop_it) { + push @d, @g; + } + else { + push @f, @g; + } + } + + return ( \@f, \@d ); +} + diff --git a/themes/SuSE/po/bootloader.pot b/themes/SuSE/po/bootloader.pot new file mode 100644 index 0000000..8e94aa6 --- /dev/null +++ b/themes/SuSE/po/bootloader.pot @@ -0,0 +1,229 @@ +# LANGUAGE translations for boot loader +# Copyright (C) 2004 SUSE LINUX AG +# +msgid "" +msgstr "" +"Project-Id-Version: bootloader\n" +"PO-Revision-Date: 2004-03-01 12:00+0200\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <i18n@suse.de>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf8\n" +"Content-Transfer-Encoding: 8bit\n" + +# ok button label +#. txt_ok +msgid "OK" +msgstr "" + +# cancel button label +#. txt_cancel +msgid "Cancel" +msgstr "" + +# reboot button label +#. txt_reboot +msgid "Reboot" +msgstr "" + +# continue button label +#. txt_continue +msgid "Continue" +msgstr "" + +#. txt_install +msgid "Installation" +msgstr "" + +#. txt_manual_install +msgid "Manual Installation" +msgstr "" + +#. txt_noacpi_install +msgid "Installation - ACPI Disabled" +msgstr "" + +#. txt_safe_install +msgid "Installation - Safe Settings" +msgstr "" + +#. txt_safe_linux +msgid "Linux - Safe Settings" +msgstr "" + +#. txt_boot_harddisk +msgid "Boot from Hard Disk" +msgstr "" + +#. txt_rescue +msgid "Rescue System" +msgstr "" + +#. txt_memtest +msgid "Memory Test" +msgstr "" + +#. txt_bootoptions +msgid "Boot Options" +msgstr "" + +# window title for exit dialog +#. txt_exit_title (see txt_exit_dialog) +msgid "Good bye..." +msgstr "" + +#. txt_exit_dialog +msgid "" +"You are leaving the graphical boot menu and\n" +"starting the text mode interface." +msgstr "" + +#. txt_help +msgid "Help" +msgstr "" + +# window title for kernel loading (see txt_load_kernel) +#. txt_load_kernel_title +msgid "Starting..." +msgstr "" + +# Keep the three newlines! +#. txt_load_kernel +msgid "Loading Linux Kernel\n\n\n" +msgstr "" + +# Keep the three newlines! +#. txt_load_memtest +msgid "Loading memtest86\n\n\n" +msgstr "" + +# info box title +#. txt_info_title +msgid "Boot loader" +msgstr "" + +# error box title +#. txt_error_title +msgid "I/O error" +msgstr "" + +# boot disk change dialog title +#. txt_change_disk_title +msgid "Change Boot Disk" +msgstr "" + +#. txt_insert_disk +#, c-format +msgid "Please insert Boot Disk %u." +msgstr "" + +#. txt_insert_disk2 +#, c-format +msgid "" +"This is Boot Disk %u.\n" +"Please insert Boot Disk %u." +msgstr "" + +#. txt_insert_disk3 +#, c-format +msgid "" +"This is not a SUSE LINUX 9.1 Boot Disk.\n" +"Please insert Boot Disk %u." +msgstr "" + +# password dialog title +#. txt_password_title +msgid "Password" +msgstr "" + +# Keep the newlines and spaces after ':'! +#. txt_password +msgid "Please enter your password: \n\n\n" +msgstr "" + +#. txt_dud_ready +msgid "Please get your Driver Update Floppy ready." +msgstr "" + +# dvd warning title +#. txt_dvd_warning_title +msgid "You're almost there..." +msgstr "" + +# Keep the newlines! +#. txt_dvd_warning +msgid "" +"\n\nIt appears that the system booted from the second side of the DVD.\n" +"If so, turn the DVD over and try again." +msgstr "" + +#. txt_dvd_warning2 +msgid "" +"This is a two-sided DVD. You have booted from the second side.\n\n" +"Please turn the DVD over, then continue." +msgstr "" + +# power off dialog title +#. txt_power_off_title +msgid "Power off" +msgstr "" + +#. txt_power_off +msgid "Do you want to halt the system now?" +msgstr "" + +#. txt_driver_update +msgid "Driver Update" +msgstr "" + +# menu entry for hard disk installation +#. txt_harddisk +msgid "Hard Disk" +msgstr "" + +# dialog title for hard disk installation +#. txt_harddisk_title +msgid "Hard Disk Installation" +msgstr "" + +#. txt_hd_diskdevice +msgid "Disk Device (scan all disks if empty)\n" +msgstr "" + +#. txt_directory +msgid "Directory\n" +msgstr "" + +# dialog title for ftp installation +#. txt_ftp_title +msgid "FTP Installation" +msgstr "" + +#. txt_server +msgid "Server\n" +msgstr "" + +#. txt_password +msgid "Password\n" +msgstr "" + +# label for ftp user input +#. txt_user1 +msgid "User (anonymous login if empty)\n" +msgstr "" + +# dialog title for nfs installation +#. txt_nfs_title +msgid "NFS Installation" +msgstr "" + +# label for smb user input +#. txt_user2 +msgid "User (using \"guest\" if empty)\n" +msgstr "" + +# dialog title for smb installation +#. txt_smb_title +msgid "SMB (Windows Share) Installation" +msgstr "" + diff --git a/themes/SuSE/po/cs.po b/themes/SuSE/po/cs.po new file mode 100644 index 0000000..c0e09dc --- /dev/null +++ b/themes/SuSE/po/cs.po @@ -0,0 +1,244 @@ +# translation of bootloader.po to cs_CZ
+# LANGUAGE translations for boot loader
+# Copyright (C) 2004 SUSE LINUX AG
+# Klara Cihlarova <koty@seznam.cz>, 2004.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: bootloader\n"
+"PO-Revision-Date: 2004-03-08 11:03+0100\n"
+"Last-Translator: Klara Cihlarova <koty@seznam.cz>\n"
+"Language-Team: cs_CZ <suse@suse.cz>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.3\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+# ok button label
+#. txt_ok
+msgid "OK"
+msgstr "OK"
+
+# cancel button label
+#. txt_cancel
+msgid "Cancel"
+msgstr "Zrušit"
+
+# reboot button label
+#. txt_reboot
+msgid "Reboot"
+msgstr "Restartovat"
+
+# continue button label
+#. txt_continue
+msgid "Continue"
+msgstr "Pokračovat"
+
+#. txt_install
+msgid "Installation"
+msgstr "Instalace"
+
+#. txt_manual_install
+msgid "Manual Installation"
+msgstr "Ruční instalace"
+
+#. txt_noacpi_install
+msgid "Installation - ACPI Disabled"
+msgstr "Instalace - bez ACPI"
+
+#. txt_safe_install
+msgid "Installation - Safe Settings"
+msgstr "Instalace - bezpečné nastavení"
+
+#. txt_safe_linux
+msgid "Linux - Safe Settings"
+msgstr "Linux - bezpečné nastavení"
+
+#. txt_boot_harddisk
+msgid "Boot from Hard Disk"
+msgstr "Spustit z disku"
+
+#. txt_rescue
+msgid "Rescue System"
+msgstr "Záchranný systém"
+
+#. txt_memtest
+msgid "Memory Test"
+msgstr "Test paměti"
+
+#. txt_bootoptions
+msgid "Boot Options"
+msgstr "Parametry startu"
+
+# window title for exit dialog
+#. txt_exit_title (see txt_exit_dialog)
+msgid "Good bye..."
+msgstr "Na shledanou..."
+
+#. txt_exit_dialog
+msgid ""
+"You are leaving the graphical boot menu and\n"
+"starting the text mode interface."
+msgstr ""
+"Opouštíte grafickou startovací nabídku\n"
+"a spouštíte textový režim."
+
+#. txt_help
+msgid "Help"
+msgstr "Nápověda"
+
+# window title for kernel loading (see txt_load_kernel)
+#. txt_load_kernel_title
+msgid "Starting..."
+msgstr "Startuji..."
+
+# Keep the three newlines!
+#. txt_load_kernel
+msgid "Loading Linux kernel\n\n\n"
+msgstr "Zavádím linuxové jádro\n\n\n"
+
+# Keep the three newlines!
+#. txt_load_memtest
+msgid "Loading memtest86\n\n\n"
+msgstr "Zavádím memtest86\n\n\n"
+
+# info box title
+#. txt_info_title
+msgid "Boot loader"
+msgstr "Zavaděč"
+
+# error box title
+#. txt_error_title
+msgid "I/O error"
+msgstr "Chyba I/O"
+
+# boot disk change dialog title
+#. txt_change_disk_title
+msgid "Change Boot Disk"
+msgstr "Změnit startovací disk"
+
+#. txt_insert_disk
+#, c-format
+msgid "Please insert Boot Disk %u."
+msgstr "Vložte disk %u."
+
+#. txt_insert_disk2
+#, c-format
+msgid ""
+"This is Boot Disk %u.\n"
+"Please insert Boot Disk %u."
+msgstr ""
+"Toto je disk %u.\n"
+"Vložte prosím disk %u."
+
+#. txt_insert_disk3
+#, c-format
+msgid ""
+"This is not a SUSE LINUX 9.1 Boot Disk.\n"
+"Please insert Boot Disk %u."
+msgstr ""
+"Toto není startovací disk SUSE LINUXu 9.1.\n"
+"Vložte startovací disk %u."
+
+# password dialog title
+#. txt_password_title
+msgid "Password"
+msgstr "Heslo"
+
+# Keep the newlines and spaces after ':'!
+#. txt_password
+msgid "Please enter your password: \n\n\n"
+msgstr "Prosím zadejte heslo: \n\n\n"
+
+#. txt_dud_ready
+msgid "Please get your Driver Update Floppy ready."
+msgstr "Připravte si disketu s ovladači."
+
+# dvd warning title
+#. txt_dvd_warning_title
+msgid "You're almost there..."
+msgstr ""
+
+# Keep the newlines!
+#. txt_dvd_warning
+msgid ""
+"\n\nIt appears that the system booted from the second side of the DVD.\n"
+"If so, turn the DVD over and try again."
+msgstr ""
+"\n\nToto se obvykle stává, když chcete systém spouštět z druhé strany DVD."
+"\n"
+"Obraťte DVD a opakujte akci."
+
+#. txt_dvd_warning2
+msgid ""
+"This is a two-sided DVD. You have booted from the second side.\n\n"
+"Please turn the DVD over, then continue."
+msgstr ""
+"Toto je oboustranné DVD. Spouštíte systém z druhé strany DVD.\n\n"
+"Obraťte prosím DVD a pokračujte."
+
+# power off dialog title
+#. txt_power_off_title
+msgid "Power off"
+msgstr "Vypnout"
+
+#. txt_power_off
+msgid "Do you want to halt the system now?"
+msgstr "Chcete nyní vypnout systém?"
+
+#. txt_driver_update +msgid "Driver Update" +msgstr "" + +# menu entry for hard disk installation +#. txt_harddisk +msgid "Hard Disk" +msgstr "" + +# dialog title for hard disk installation +#. txt_harddisk_title +msgid "Hard Disk Installation" +msgstr "" + +#. txt_hd_diskdevice +msgid "Disk Device (scan all disks if empty)\n" +msgstr "" + +#. txt_directory +msgid "Directory\n" +msgstr "" + +# dialog title for ftp installation +#. txt_ftp_title +msgid "FTP Installation" +msgstr "" + +#. txt_server +msgid "Server\n" +msgstr "" + +#. txt_password +msgid "Password\n" +msgstr "" + +# label for ftp user input +#. txt_user1 +msgid "User (anonymous login if empty)\n" +msgstr "" + +# dialog title for nfs installation +#. txt_nfs_title +msgid "NFS Installation" +msgstr "" + +# label for smb user input +#. txt_user2 +msgid "User (using \"guest\" if empty)\n" +msgstr "" + +# dialog title for smb installation +#. txt_smb_title +msgid "SMB (Windows Share) Installation" +msgstr "" + diff --git a/themes/SuSE/po/de.po b/themes/SuSE/po/de.po new file mode 100644 index 0000000..43e18b9 --- /dev/null +++ b/themes/SuSE/po/de.po @@ -0,0 +1,242 @@ +# translation of de.po to German +# LANGUAGE translations for boot loader +# Copyright (C) 2004 SUSE LINUX AG +# Antje Faber <afaber@suse.de>, 2004. +# +msgid "" +msgstr "" +"Project-Id-Version: de\n" +"PO-Revision-Date: 2004-03-09 18:37GMT\n" +"Last-Translator: Antje Faber <afaber@suse.de>\n" +"Language-Team: German <i18n@suse.de>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.0.2\n" + +# ok button label +#. txt_ok +msgid "OK" +msgstr "Ok" + +# cancel button label +#. txt_cancel +msgid "Cancel" +msgstr "Verwerfen" + +# reboot button label +#. txt_reboot +msgid "Reboot" +msgstr "Neustart" + +# continue button label +#. txt_continue +msgid "Continue" +msgstr "Fortfahren" + +#. txt_install +msgid "Installation" +msgstr "Installation" + +#. txt_manual_install +msgid "Manual Installation" +msgstr "Manuelle Installation" + +#. txt_noacpi_install +msgid "Installation - ACPI Disabled" +msgstr "Installation - ACPI deaktiviert" + +#. txt_safe_install +msgid "Installation - Safe Settings" +msgstr "Installation - Sichere Einstellungen" + +#. txt_safe_linux +msgid "Linux - Safe Settings" +msgstr "Linux - Sichere Einstellungen" + +#. txt_boot_harddisk +msgid "Boot from Hard Disk" +msgstr "Von Festplatte booten" + +#. txt_rescue +msgid "Rescue System" +msgstr "Rettungssystem" + +#. txt_memtest +msgid "Memory Test" +msgstr "Speichertest" + +#. txt_bootoptions +msgid "Boot Options" +msgstr "Bootoptionen" + +# window title for exit dialog +#. txt_exit_title (see txt_exit_dialog) +msgid "Good bye..." +msgstr "Tschüs..." + +#. txt_exit_dialog +msgid "" +"You are leaving the graphical boot menu and\n" +"starting the text mode interface." +msgstr "" +"Sie verlassen das grafische Bootmenü und\n" +"kommen in den Textmodus." + +#. txt_help +msgid "Help" +msgstr "Hilfe" + +# window title for kernel loading (see txt_load_kernel) +#. txt_load_kernel_title +msgid "Starting..." +msgstr "Starten..." + +# Keep the three newlines! +#. txt_load_kernel +msgid "Loading Linux Kernel\n\n\n" +msgstr "Laden des Linux-Kernels\n\n\n" + +# Keep the three newlines! +#. txt_load_memtest +msgid "Loading memtest86\n\n\n" +msgstr "Laden von memtest86\n\n\n" + +# info box title +#. txt_info_title +msgid "Boot loader" +msgstr "Bootloader" + +# error box title +#. txt_error_title +msgid "I/O error" +msgstr "E/A-Fehler" + +# boot disk change dialog title +#. txt_change_disk_title +msgid "Change Boot Disk" +msgstr "Bootdiskette wechseln" + +#. txt_insert_disk +#, c-format +msgid "Please insert Boot Disk %u." +msgstr "Legen Sie Bootdiskette %u ein." + +#. txt_insert_disk2 +#, c-format +msgid "" +"This is Boot Disk %u.\n" +"Please insert Boot Disk %u." +msgstr "" +"Dies ist die Bootdiskette %u.\n" +"Legen Sie die Bootdiskette %u ein." + +#. txt_insert_disk3 +#, c-format +msgid "" +"This is not a SUSE LINUX 9.1 Boot Disk.\n" +"Please insert Boot Disk %u." +msgstr "" +"Dies ist keine SUSE LINUX 9.1-Bootdiskette.\n" +"Legen Sie die Bootdiskette %u ein." + +# password dialog title +#. txt_password_title +msgid "Password" +msgstr "Passwort" + +# Keep the newlines and spaces after ':'! +#. txt_password +msgid "Please enter your password: \n\n\n" +msgstr "Bitte geben Sie Ihr Passwort ein: \n\n\n" + +#. txt_dud_ready +msgid "Please get your Driver Update Floppy ready." +msgstr "Halten Sie Ihre Treiber-Update-Diskette bereit." + +# dvd warning title +#. txt_dvd_warning_title +msgid "You're almost there..." +msgstr "Sie haben es fast geschafft." + +# Keep the newlines! +#. txt_dvd_warning +msgid "" +"\n\nIt appears that the system booted from the second side of the DVD.\n" +"If so, turn the DVD over and try again." +msgstr "" +"\n\nEs scheint, dass das System von der zweiten Seite der DVD gestartet wurde.\n" +"Falls dies zutrifft, drehen Sie die DVD um, und versuchen Sie es erneut." + +#. txt_dvd_warning2 +msgid "" +"This is a two-sided DVD. You have booted from the second side.\n\n" +"Please turn the DVD over, then continue." +msgstr "" +"Dies ist eine zweiseitige DVD. Sie haben von der zweiten Seite gebootet.\n\n" +"Drehen Sie die DVD um, und fahren Sie dann fort." + +# power off dialog title +#. txt_power_off_title +msgid "Power off" +msgstr "Ausschalten" + +#. txt_power_off +msgid "Do you want to halt the system now?" +msgstr "Wollen Sie das System nun anhalten?" + +#. txt_driver_update +msgid "Driver Update" +msgstr "Treiber-Update" + +# menu entry for hard disk installation +#. txt_harddisk +msgid "Hard Disk" +msgstr "Festplatte" + +# dialog title for hard disk installation +#. txt_harddisk_title +msgid "Hard Disk Installation" +msgstr "Festplatten-Installation" + +#. txt_hd_diskdevice +msgid "Disk Device (scan all disks if empty)\n" +msgstr "Plattengerät (Platten scannen, falls leer)\n" + +#. txt_directory +msgid "Directory\n" +msgstr "Verzeichnis\n" + +# dialog title for ftp installation +#. txt_ftp_title +msgid "FTP Installation" +msgstr "FTP-Installation" + +#. txt_server +msgid "Server\n" +msgstr "Server\n" + +#. txt_password +msgid "Password\n" +msgstr "Passwort\n" + +# label for ftp user input +#. txt_user1 +msgid "User (anonymous login if empty)\n" +msgstr "Benutzer (anonymous-Anmeldung, falls leer)\n" + +# dialog title for nfs installation +#. txt_nfs_title +msgid "NFS Installation" +msgstr "NFS-Installation" + +# label for smb user input +#. txt_user2 +msgid "User (using \"guest\" if empty)\n" +msgstr "Benutzer (\"guest\" verwenden, falls leer)\n" + +# dialog title for smb installation +#. txt_smb_title +msgid "SMB (Windows Share) Installation" +msgstr "SMB (Windows Share)-Installation" + diff --git a/themes/SuSE/po/sk.po b/themes/SuSE/po/sk.po new file mode 100644 index 0000000..0d03090 --- /dev/null +++ b/themes/SuSE/po/sk.po @@ -0,0 +1,243 @@ +# translation of bootloader.po to
+# LANGUAGE translations for boot loader
+# Copyright (C) 2004 SUSE LINUX AG
+# , 2004.
+# , 2004.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: bootloader\n"
+"PO-Revision-Date: 2004-03-08 08:51+0100\n"
+"Last-Translator: \n"
+"Language-Team: <sk@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.3\n"
+
+# ok button label
+#. txt_ok
+msgid "OK"
+msgstr "OK"
+
+# cancel button label
+#. txt_cancel
+msgid "Cancel"
+msgstr "Zrušiť"
+
+# reboot button label
+#. txt_reboot
+msgid "Reboot"
+msgstr "Reštartovať"
+
+# continue button label
+#. txt_continue
+msgid "Continue"
+msgstr "Pokračovať"
+
+#. txt_install
+msgid "Installation"
+msgstr "Inštalácia"
+
+#. txt_manual_install
+msgid "Manual Installation"
+msgstr "Manuálna inštalácia"
+
+#. txt_noacpi_install
+msgid "Installation - ACPI Disabled"
+msgstr "Inštalácia - ACPI vypnuté"
+
+#. txt_safe_install
+msgid "Installation - Safe Settings"
+msgstr "Inštalácia - Bezpečné nastavenie"
+
+#. txt_safe_linux
+msgid "Linux - Safe Settings"
+msgstr "Linux - Bezpečné nastavenie"
+
+#. txt_boot_harddisk
+msgid "Boot from Hard Disk"
+msgstr "Spustiť systém z pevného disku"
+
+#. txt_rescue
+msgid "Rescue System"
+msgstr "Záchranný systém"
+
+#. txt_memtest
+msgid "Memory Test"
+msgstr "Test pamäti"
+
+#. txt_bootoptions
+msgid "Boot Options"
+msgstr "Možnosti štartu"
+
+# window title for exit dialog
+#. txt_exit_title (see txt_exit_dialog)
+msgid "Good bye..."
+msgstr "Dovidenia..."
+
+#. txt_exit_dialog
+msgid ""
+"You are leaving the graphical boot menu and\n"
+"starting the text mode interface."
+msgstr ""
+"Opúšťate grafické menu štartu a spúšťate\n"
+"textové používateľské rozhranie."
+
+#. txt_help
+msgid "Help"
+msgstr "Pomocník"
+
+# window title for kernel loading (see txt_load_kernel)
+#. txt_load_kernel_title
+msgid "Starting..."
+msgstr "Spúšťam..."
+
+# Keep the three newlines!
+#. txt_load_kernel
+msgid "Loading Linux kernel\n\n\n"
+msgstr "Načítavam jadro Linuxu\n\n\n"
+
+# Keep the three newlines!
+#. txt_load_memtest
+msgid "Loading memtest86\n\n\n"
+msgstr "Načítavam memtest86\n\n\n"
+
+# info box title
+#. txt_info_title
+msgid "Boot loader"
+msgstr "Správca štartu"
+
+# error box title
+#. txt_error_title
+msgid "I/O error"
+msgstr "Chyba V/V"
+
+# boot disk change dialog title
+#. txt_change_disk_title
+msgid "Change Boot Disk"
+msgstr "Zmena štartovacej diskety"
+
+#. txt_insert_disk
+#, c-format
+msgid "Please insert Boot Disk %u."
+msgstr "Prosím, vložte štartovaciu disketu %u."
+
+#. txt_insert_disk2
+#, c-format
+msgid ""
+"This is Boot Disk %u.\n"
+"Please insert Boot Disk %u."
+msgstr ""
+"Toto je disketa %u.\n"
+"Prosím, vložte disketu %u."
+
+#. txt_insert_disk3
+#, c-format
+msgid ""
+"This is not a SUSE LINUX 9.1 Boot Disk.\n"
+"Please insert Boot Disk %u."
+msgstr ""
+"Toto nie je štartovacia disketa SUSE LINUX 9.1.\n"
+"Prosím, vložte štartovaciu disketu %u."
+
+# password dialog title
+#. txt_password_title
+msgid "Password"
+msgstr "Heslo"
+
+# Keep the newlines and spaces after ':'!
+#. txt_password
+msgid "Please enter your password: \n\n\n"
+msgstr "Prosím, zadajte heslo: \n\n\n"
+
+#. txt_dud_ready
+msgid "Please get your Driver Update Floppy ready."
+msgstr "Prosím, pripravte si disketu s aktualizovanými ovládačmi."
+
+# dvd warning title
+#. txt_dvd_warning_title
+msgid "You're almost there..."
+msgstr "Už to skoro bude..."
+
+# Keep the newlines!
+#. txt_dvd_warning
+msgid ""
+"\n\nIt appears that the system booted from the second side of the DVD.\n"
+"If so, turn the DVD over and try again."
+msgstr ""
+"\n\nVyzerá to, že ste systém spustili z druhej strany DVD.\n"
+"Ak to tak je, otočte DVD médium a skúste to znovu."
+
+#. txt_dvd_warning2
+msgid ""
+"This is a two-sided DVD. You have booted from the second side.\n\n"
+"Please turn the DVD over, then continue."
+msgstr ""
+"Toto je obojstranné médium DVD. Systém ste spustili z druhej strany.\n\n"
+"Prosím, otočte médium a potom pokračujte."
+
+# power off dialog title
+#. txt_power_off_title
+msgid "Power off"
+msgstr "Vypnúť"
+
+#. txt_power_off
+msgid "Do you want to halt the system now?"
+msgstr "Chcete teraz počítač vypnúť?"
+
+#. txt_driver_update +msgid "Driver Update" +msgstr "" + +# menu entry for hard disk installation +#. txt_harddisk +msgid "Hard Disk" +msgstr "" + +# dialog title for hard disk installation +#. txt_harddisk_title +msgid "Hard Disk Installation" +msgstr "" + +#. txt_hd_diskdevice +msgid "Disk Device (scan all disks if empty)\n" +msgstr "" + +#. txt_directory +msgid "Directory\n" +msgstr "" + +# dialog title for ftp installation +#. txt_ftp_title +msgid "FTP Installation" +msgstr "" + +#. txt_server +msgid "Server\n" +msgstr "" + +#. txt_password +msgid "Password\n" +msgstr "" + +# label for ftp user input +#. txt_user1 +msgid "User (anonymous login if empty)\n" +msgstr "" + +# dialog title for nfs installation +#. txt_nfs_title +msgid "NFS Installation" +msgstr "" + +# label for smb user input +#. txt_user2 +msgid "User (using \"guest\" if empty)\n" +msgstr "" + +# dialog title for smb installation +#. txt_smb_title +msgid "SMB (Windows Share) Installation" +msgstr "" + diff --git a/themes/SuSE/splash.pcx b/themes/SuSE/splash.pcx Binary files differnew file mode 100644 index 0000000..cf35ae6 --- /dev/null +++ b/themes/SuSE/splash.pcx diff --git a/themes/SuSE/system.inc b/themes/SuSE/system.inc new file mode 100644 index 0000000..54df9d8 --- /dev/null +++ b/themes/SuSE/system.inc @@ -0,0 +1,263 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% Some basic definitions. +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% some key codes +/keyEsc 0x0000001b def +/keyEnter 0x0000000d def +/keyTab 0x00000009 def +/keyF1 0x3b000000 def +/keyF2 0x3c000000 def +/keyF3 0x3d000000 def +/keyF4 0x3e000000 def +/keyF5 0x3f000000 def +/keyF6 0x40000000 def +/keyF7 0x41000000 def +/keyF8 0x42000000 def +/keyF9 0x43000000 def +/keyF10 0x44000000 def +/keyF11 0x85000000 def +/keyF12 0x86000000 def +/keyHome 0x47000000 def +/keyUp 0x48000000 def +/keyPgUp 0x49000000 def +/keyLeft 0x4b000000 def +/keyRight 0x4d000000 def +/keyEnd 0x4f000000 def +/keyDown 0x50000000 def +/keyPgDown 0x51000000 def +/keyIns 0x52000000 def +/keyDel 0x53000000 def +/keyShiftF1 0x54000000 def +/keyShiftF2 0x55000000 def +/keyShiftF3 0x56000000 def +/keyShiftF4 0x57000000 def +/keyShiftF5 0x58000000 def +/keyShiftF6 0x59000000 def +/keyShiftF7 0x5a000000 def +/keyShiftF8 0x5b000000 def +/keyShiftF9 0x5c000000 def +/keyShiftF10 0x5d000000 def +/keyShiftF11 0x87000000 def +/keyShiftF12 0x88000000 def +/keyCtrlF1 0x5e000000 def +/keyCtrlF2 0x5f000000 def +/keyCtrlF3 0x60000000 def +/keyCtrlF4 0x61000000 def +/keyCtrlF5 0x62000000 def +/keyCtrlF6 0x63000000 def +/keyCtrlF7 0x64000000 def +/keyCtrlF8 0x65000000 def +/keyCtrlF9 0x66000000 def +/keyCtrlF10 0x67000000 def +/keyAltF1 0x68000000 def +/keyAltF2 0x69000000 def +/keyAltF3 0x6a000000 def +/keyAltF4 0x6b000000 def +/keyAltF5 0x6c000000 def +/keyAltF6 0x6d000000 def +/keyAltF7 0x6e000000 def +/keyAltF8 0x6f000000 def +/keyAltF9 0x70000000 def +/keyAltF10 0x71000000 def +/keyCtrlLeft 0x73000000 def +/keyCtrlRight 0x74000000 def +/keyCtrlEnd 0x75000000 def +/keyCtrlDown 0x76000000 def +/keyCtrlHome 0x76000000 def +/keyCtrlUp 0x84000000 def +/keyStatus 0xff000000 def + +/statusAlt 0x0208 def +/statusAltL 0x0200 def +/statusAltR 0x0008 def +/statusCtrl 0x0104 def +/statusShift 0x0003 def + +% boot loader +/lilo bootloader 0 eq def +/syslinux bootloader 1 eq def +/grub bootloader 2 eq def + +% bool values +/true 0 0 eq def +/false 0 0 ne def + +% type values +/t_none 0 def +/t_int 1 def +/t_unsigned 2 def +/t_bool 3 def +/t_string 4 def +/t_code 5 def +/t_ret 6 def +/t_prim 7 def +/t_sec 8 def +/t_dict_idx 9 def +/t_array 10 def +/t_end 11 def +/t_ptr 12 def + +/.value { t_int settype } def +/.undef 0 t_none settype def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Print string (for debugging). +% +% ( string ) ==> ( ) +% +/string.print { + dup + currentpoint currentpoint 5 -1 roll strsize image moveto + show +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Print number (for debugging). +% +% ( number ) ==> ( ) +% +/number.print { + 32 string + exch over + "%08x" exch sprintf + dup string.print + free +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Print obj (for debugging). +% +% ( obj ) ==> ( ) +% +/obj.print { + 64 string + exch dup + .value exch gettype + "%x:%08x" 3 index sprintf + dup string.print + free +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Print (for debugging). +% +% ( obj ) ==> ( ) +% +/print { + dup gettype t_int eq { number.print return } if + dup gettype t_string eq { string.print return } if + obj.print +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Convert object to pointer. +% +% ( obj ) ==> ( ptr ) +% +/cvp { t_ptr settype } def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Convert object to string. +% +% ( obj ) ==> ( string ) +% +/cvs { t_string settype } def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Arguments like snprintf. +% +% ( obj_1 ... obj_n string_1 string_2 ) ==> ( ) +% +/sprintf { + dup cvp length exch snprintf +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Allocate new string. +% +% ( size ) ==> ( string ) +/string { + 1 add malloc cvs +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Increment variable. +% +% ( dict_ref ) ==> ( ) +% +/inc { + dup exec 1 add def +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Copy src to dst. +% +% Watch overlapping src & dst! +% +% ( dst src ) ==> ( dst ) +% +/strcpy { + "%s" 2 index sprintf +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Duplicate string. +% +% ( string ) ==> ( string ) +% +/strdup { + dup length string exch strcpy +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Test for AltGr. +% +% ( ) ==> ( bool ) +% +/is_altGr { + keystat statusAltR and 0 ne keystat statusAltL and 0 eq and +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Keyboard mapping. +% +% ( key ) ==> ( key ) +% +/mapkey { + dup 24 shr 0xff and /key.code exch def + is_altGr { + % bios is too smart... + key.code 0x78 ge key.code 0x83 le and { /key.code key.code 0x76 sub def } if + } if + 0 1 config.keymap length 1 sub { + config.keymap exch get + dup 0 get key.code eq { + 1 + keystat statusShift and { pop 2 } if + is_altGr { pop 3 } if + get + exch pop + } { + pop + } ifelse + } for +} def + + diff --git a/themes/SuSE/window.inc b/themes/SuSE/window.inc new file mode 100644 index 0000000..6af0d47 --- /dev/null +++ b/themes/SuSE/window.inc @@ -0,0 +1,637 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% window code +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% public words: +% +% window.dialog ( ) ==> ( window ) +% - create a new dialog +% +% window.init ( window ) ==> ( ) +% - initialize window +% +% window.show ( window ) ==> ( ) +% - draw window +% +% window.current ( ) ==> ( window ) +% - the top level window +% +% window.action ( ) ==> ( action ) +% - recent window action +% +% window.input ( key_in ) ==> ( key_out ) +% - handle keyboard input +% +% window.done ( ) ==> ( ) +% - close top level window +% +% +% constants: +% - window.action +% actNothing - do nothing +% actExit - leave boot menu +% actCloseInfo - close info window +% actPassword - password entered +% actStart - boot kernel +% actEject - eject CD +% actPowerOff - turn computer off +% actRedraw - redraw everything +% actNoClose - don't close dialog (it's a flag) +% + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% window related global variables +% + +% all open windows are stacked here +/window.list 8 array def +/window.list.index 0 def + +% the top level window +% /window.current + +% action selected by closing window +/window.action actNothing def + +% window field definitions +/widget.size 0 def +/newfield { widget.size def /widget.size widget.size 1 add def } def + +/.type newfield +/.x newfield +/.y newfield +/.width newfield +/.height newfield +/.width.min newfield +/.position newfield +/.color.fg newfield +/.color.bg newfield +/.font newfield +/.saved newfield +/.title newfield +/.title.fg newfield +/.title.bg newfield +/.title.height newfield +/.text newfield +/.text.x newfield +/.text.y newfield +/.buttons newfield +/.button.y newfield +/.ed newfield +/.ed.font newfield +/.ed.list newfield +/.ed.buffer.list newfield +/.ed.text.list newfield +/.ed.width newfield +/.ed.focus newfield +/.xmenu newfield +/.xmenu.update newfield +/.dont_free newfield + +% window types +/t_dialog 100 def +/t_help 101 def +/t_main 102 def +/t_xmenu 103 def + +% actions +/actNothing 0 def +/actExit 1 def +/actCloseInfo 2 def +/actPassword 3 def +/actStart 4 def +/actEject 5 def +/actPowerOff 6 def +/actRedraw 7 def +/actRedrawPanel 8 def +/actInstallOK 9 def +/actInstallCancel 10 def +/actNoClose 0x100 def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Create new dialog window. +% +% ( ) ==> ( window ) +% +/window.dialog { + widget.size array + dup .type t_dialog put + dup .position 8 put % centered at 8/10 of screen height + dup .x 0 put + dup .y 0 put + dup .width.min 0 put + dup .color.fg black put + dup .color.bg lightgray put + dup .font font.normal put + dup .title.fg white put + dup .title.bg title.bg put + dup .title.height help.title.height put + dup .text.x 12 put + dup .text.y help.title.height 10 add put +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Handle keyboard input. +% +% ( key_in ) ==> ( key_out ) +% +/window.input { + window.current .undef ne { + window.current .type get + dup t_dialog eq { exch dialog.input exch } if + dup t_help eq { exch help.input exch } if + dup t_main eq { exch main.input exch } if + dup t_xmenu eq { exch xmenu.input exch } if + pop + + % maybe there is an editable input field + dup 0 ne { + window.current .ed get .undef ne { + window.current .ed.font get setfont + window.current .color.fg get setcolor + window.current .ed get exch edit.input + 0 + } if + } if + + % only top level window gets input + pop 0 + + } if +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Initialize window. +% +% ( window ) ==> ( ) +% +/window.init { + dup .type get + dup t_dialog eq { pop dialog.init return } if + dup t_help eq { pop help.init return } if + dup t_main eq { pop main.init return } if + dup t_xmenu eq { pop xmenu.init return } if + pop +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Show window. +% +% ( window ) ==> ( ) +% +/window.show { + dup .type get + dup t_dialog eq { pop dialog.show return } if + dup t_help eq { pop help.show return } if + dup t_main eq { pop main.show return } if + dup t_xmenu eq { pop xmenu.show return } if + pop +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Add window to list. +% +% ( window ) ==> ( ) +% +/window.push { + window.list.index window.list length ge { pop return } if + /window.current over def + window.list window.list.index rot put + /window.list.index window.list.index 1 add def +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Remove window from list. +% +% ( ) ==> ( window ) +% +/window.pop { + window.list.index 0 eq { .undef return } if + /window.list.index window.list.index 1 sub def + window.list window.list.index get + window.list window.list.index .undef put + /window.current + window.list.index 0 eq { .undef } { window.list window.list.index 1 sub get } ifelse + def +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Close top level window. +% +% ( ) ==> ( ) +% +/window.done { + window.current .undef ne { + window.current dup .type get + dup t_help eq { help.done } if + pop + % restore saved background and free bg image + dup .saved get .undef ne { + dup .x get 1 sub over .y get 1 sub moveto + dup .saved get dup restorescreen free + dup .saved .undef put + } if + % free input field memory + dup .ed get .undef ne { + dup .ed get 2 get free % background + dup .ed get free + dup .ed .undef put + } if + pop + % remove it from window list + window.pop + % free buttons & button list + dup .buttons get + dup .undef ne { + dup length 0 gt { + dup length 1 sub 0 1 rot { + over exch get free + } for + } if + } if + free + % free window + dup .dont_free get { pop } { free } ifelse + } if +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Handle keyboard input. +% +% ( key_in ) ==> ( key_out ) +% +/dialog.input { + dup 0 eq { return } if + + /window.buttons window.current .buttons get def + + window.buttons .undef ne { window.buttons length { + + dup keyEnter eq { + window.buttons window.findselected + over over get 7 get /window.action exch def get + dup button.press 100000 usleep + window.action actNoClose and { + window.action dialog.specialaction { button.show } if + } { + pop window.done + } ifelse + pop 0 + } if + + window.current .ed.list get { + dup keyDown eq { + window.current .ed.focus get + window.current .ed.list get over get edit.hidecursor + + 1 add window.current .ed.list get length mod + window.current .ed.focus 2 index put + window.current .ed.list get exch get edit.showcursor + pop 0 + } if + + dup keyUp eq { + window.current .ed.focus get + window.current .ed.list get over get edit.hidecursor + + 1 sub window.current .ed.list get length exch over add exch mod + window.current .ed.focus 2 index put + window.current .ed.list get exch get edit.showcursor + pop 0 + } if + + dup keyTab eq { + window.findselected 1 add window.buttons length mod + window.selectbutton + pop 0 + } if + + } { + dup keyTab eq over keyRight eq or over keyDown eq or { + window.findselected 1 add window.buttons length mod + window.selectbutton + pop 0 + } if + + dup keyLeft eq over keyUp eq or { + window.findselected window.buttons length 1 sub add window.buttons length mod + window.selectbutton + pop 0 + } if + } ifelse + + dup window.findkey dup 0 ge { + window.buttons exch + over over get 7 get /window.action exch def get + dup button.press 100000 usleep + window.action actNoClose and { + window.action dialog.specialaction { button.show } if + } { + pop window.done + } ifelse + pop 0 + } { + pop + } ifelse + + } if } if + + + % maybe there are input fields + dup 0 ne { + window.current .ed.list get dup { + window.current .ed.font get setfont + window.current .color.fg get setcolor + + window.current .ed.focus get get exch edit.input + 0 + } { pop } ifelse + } if + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Find selected button. +% +% ( ) ==> ( button_idx ) +% +/window.findselected { + 0 + 0 1 window.buttons length 1 sub { + dup + window.buttons exch get 5 get + { + exch pop exit + } { + pop + } ifelse + } for +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Find button for key. +% +% ( key ) ==> ( button_idx ) +% +% button_idx = -1 if not found +% +/window.findkey { + /window.key exch def + -1 + window.key 0 eq { return } if + 0 1 window.buttons length 1 sub { + dup + window.buttons exch get 6 get window.key eq + { + exch pop exit + } { + pop + } ifelse + } for +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Select button. +% +% ( button_idx ) ==> ( ) +% +/window.selectbutton { + window.findselected + over over eq { + pop pop + } { + window.buttons exch get button.notdefault button.show + window.buttons exch get button.default button.show + } ifelse +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Initialize dialog window. +% +% ( window ) ==> ( ) +% +/dialog.init { + /dialog.tmp exch def + + dialog.tmp .font get setfont + + dialog.tmp .text get dup "" ne { strsize } { pop 0 0 } ifelse + /dialog.height exch dialog.tmp .text.y get 10 add add def + /dialog.width exch dialog.tmp .text.x get 1 add 2 mul add dialog.tmp .width.min get max def + + /dialog.width dialog.tmp .title get strsize pop dialog.tmp .text.x get 1 add 2 mul add dialog.width max def + + dialog.tmp .ed.text.list get dup { + /dialog.width + dialog.tmp .ed.width get dialog.tmp .text.x get 1 add 2 mul add 8 add dialog.width max + def + { + strsize + /dialog.height exch dialog.height add def + /dialog.width exch dialog.tmp .text.x get 1 add 2 mul add dialog.width max def + } forall + } { pop } ifelse + + dialog.tmp .ed.buffer.list get dup { + length lineheight 10 add mul /dialog.height exch dialog.height add def + } { pop } ifelse + + /window.buttons dialog.tmp .buttons get def + + /dialog.button.y dialog.height 5 add def + + window.buttons .undef ne { window.buttons length { + /dialog.height window.buttons 0 get 3 get dialog.button.y add 8 add def + } if } if + + /dialog.y screen.size exch pop dialog.tmp .position get mul 10 div dialog.height sub 2 div def + + window.buttons .undef ne { window.buttons length { + 10 + 0 1 window.buttons length 1 sub { + window.buttons exch get + dup 1 dialog.button.y dialog.y add put + 2 get 10 add add + } for + + dialog.width max /dialog.width exch def + } if } if + + /dialog.x screen.size pop dialog.width sub 2 div def + + window.buttons .undef ne { window.buttons length { + % calculate button x positions + dialog.width 0 + 0 1 window.buttons length 1 sub { + window.buttons exch get 2 get add + } for + sub window.buttons length 1 add div + dialog.x over add + 0 1 window.buttons length 1 sub { + window.buttons exch get + over over 0 rot put + 2 get add over add + } for + pop pop + } if } if + + % store values + + dialog.tmp + dup .x dialog.x put + dup .y dialog.y put + dup .width dialog.width put + dup .height dialog.height put + .button.y dialog.button.y put + + /dialog.tmp .undef def +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Draw dialog window. +% +% ( window ) ==> ( ) +% +/dialog.show { + /dialog.tmp exch def + + % put into list early, so drawing functions can access it there + dialog.tmp window.push + + % now start drawing + + dialog.tmp .x get 1 sub dialog.tmp .y get 1 sub moveto + white black + dialog.tmp .width get 2 add dialog.tmp .height get 2 add + over over + dialog.tmp .ed.list get { xsavescreen } { savescreen } ifelse dialog.tmp .saved rot put + drawborder + + dialog.tmp .color.bg get setcolor + dialog.tmp .x get dialog.tmp .y get moveto + dialog.tmp .width get dialog.tmp .height get fillrect + + dialog.tmp .title.bg get setcolor + dialog.tmp .x get 1 add dialog.tmp .y get 1 add moveto + dialog.tmp .width get 2 sub dialog.tmp .title.height get 1 sub fillrect + + dialog.tmp .x get 10 add dialog.tmp .y get 3 add moveto + dialog.tmp .title.fg get setcolor + dialog.tmp .title get show + + dialog.tmp .color.fg get setcolor + dialog.tmp .x get dialog.tmp .y get moveto + dialog.tmp .text.x get dialog.tmp .text.y get rmoveto + dialog.tmp .text get show + + dialog.tmp .ed.text.list get dup { + /dialog.tmp.idx 0 def + { + show + dialog.tmp .ed.buffer.list get dialog.tmp.idx get + + dup { + + 3 7 rmoveto + + /dialog.tmp.buf dialog.tmp .ed.list get dialog.tmp.idx get def + + dialog.tmp.buf { + /dialog.tmp.doinit false def + } { + /dialog.tmp.doinit true def + /dialog.tmp.buf [ + currentpoint + dialog.tmp .ed.width get fontheight 2 add savescreen + 0 0 + 0 0 0 + ] def + } ifelse + + dialog.tmp.buf 3 2 index put + dialog.tmp.buf 4 rot cvp length put + + dialog.tmp .ed.list get dialog.tmp.idx dialog.tmp.buf put + + currentcolor + currentpoint over 1 sub over 2 sub moveto + black white dialog.tmp .ed.width get 2 add fontheight 4 add drawborder + moveto -3 lineheight 10 add 7 sub rmoveto + setcolor + + dialog.tmp.doinit { + dialog.tmp.buf "" edit.init + } { + % we really need a redraw function... + dialog.tmp.buf dup 3 get edit.init + } ifelse + dialog.tmp .ed.focus get dialog.tmp.idx ne { dialog.tmp.buf edit.hidecursor } if + + } { pop } ifelse + + /dialog.tmp.idx inc + } forall + } { pop } ifelse + + dialog.tmp .buttons get .undef ne { dialog.tmp .buttons get length { + 0 1 dialog.tmp .buttons get length 1 sub { + dialog.tmp .buttons get exch get button.show + } for + } if } if + + /dialog.tmp .undef def + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Do something without closing the window. +% +% ( action ) ==> ( true|false ) +% +% Returns whether the window still exists. +% +/dialog.specialaction { + actNoClose not and + + true exch + + dup actEject eq { + bootdrive eject pop + } if + + dup actPowerOff eq { + poweroff + } if + + dup actInstallOK eq { + install.ok + exch not exch + } if + +% dup actInstallCancel eq { +% install.cancel +% exch not exch +% } if + + pop +} def + + diff --git a/themes/SuSE/xmenu.inc b/themes/SuSE/xmenu.inc new file mode 100644 index 0000000..e8fa819 --- /dev/null +++ b/themes/SuSE/xmenu.inc @@ -0,0 +1,258 @@ +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% List dialog handling. +% +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Some global vars. +% +/xmenu.vspace 4 def +/xmenu.hspace 12 def +/xmenu.light white def +/xmenu.dark black def +/xmenu.font font.normal def +/xmenu.normal.bg lightgray def +/xmenu.normal.fg black def +/xmenu.selected.fg white def +/xmenu.selected.bg 0x6c6c6c newcolor + + +% xmenu layout +% +% [ selected_entry string_list x y panel_x ] +% +/.xm_current 0 def % selected entry +/.xm_list 1 def % string list +/.xm_x 2 def % menu x pos +/.xm_y 3 def % menu y pos +/.xm_width 4 def % menu width +/.xm_height 5 def % menu height +/.xm_panel_x 6 def % panel entry x pos +/.xm_panel_width 7 def % panel entry width +/.xm_panel_height 8 def % panel entry height +/.xm_size 9 def % xmenu size + + +% short hands +/xmenu.x { xmenu .xm_x get } def +/xmenu.y { xmenu .xm_y get } def +/xmenu.width { xmenu .xm_width get } def +/xmenu.height { xmenu .xm_height get } def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Create new xmenu. +% +% ( ) ==> ( window ) +% +/window.xmenu { + widget.size array + dup .type t_xmenu put +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Handle keyboad input. +% +% ( key_in ) ==> ( key_out ) +% +/xmenu.input { + dup 0 eq { return } if + + dup keyEsc eq { + xmenu 0 xmenu.oldentry put + window.done + pop 0 + } if + + dup keyEnter eq { + window.current .xmenu.update get + window.done + exec + pop 0 + } if + + dup keyDown eq { + xmenu 0 get 1 add xmenu.select + pop 0 + } if + + dup keyUp eq { + xmenu 0 get 1 sub xmenu.select + pop 0 + } if + + dup keyF1 eq { + show_help + pop 0 + } if + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Calculate menu sizes. +% +% ( ) ==> ( ) +% +/xmenu.sizes { + /xmenu.lheight xmenu.font setfont fontheight xmenu.vspace dup add add def + + xmenu .xm_height + xmenu .xm_list get length xmenu.lheight mul + put + + xmenu .xm_width + 0 xmenu .xm_list get { strsize pop max } forall xmenu.hspace 2 mul add + put + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Init and show menu. +% +% ( window ) ==> ( ) +% +% xmenu: [ selected_entry [ text0 text1 ... ] x y ] +% +/xmenu.init { + /xmenu over .xmenu get def + + xmenu.sizes + + xmenu.x 1 sub xmenu.y 1 sub moveto + xmenu.light xmenu.dark + xmenu.width 2 add xmenu.height 2 add + over over savescreen /xmenu.saved exch def + drawborder + + 0 1 xmenu .xm_list get length 1 sub { xmenu.viewentry } for + + /xmenu.oldentry xmenu .xm_current get def + + dup .x xmenu.x put + dup .y xmenu.y put + .saved xmenu.saved put + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Draw xmenu. +% +% ( window ) ==> ( ) +% +/xmenu.show { + window.push +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Draw single entry. +% +% ( entry ) ==> ( ) +% +/xmenu.viewentry { + xmenu.font setfont + + dup xmenu.lheight mul xmenu.y add /xmenu.pos.y exch def + + xmenu.x xmenu.pos.y moveto + dup xmenu .xm_current get eq { xmenu.selected.bg } { xmenu.normal.bg } ifelse + setcolor xmenu.width xmenu.lheight fillrect + + dup xmenu .xm_current get eq { xmenu.selected.fg } { xmenu.normal.fg } ifelse setcolor + xmenu.x xmenu.hspace add xmenu.pos.y xmenu.vspace add moveto + xmenu .xm_list get over get show + + dup xmenu .xm_current get eq { + xmenu.x xmenu.pos.y moveto + xmenu.dark xmenu.light xmenu.width xmenu.lheight drawborder + } if + + pop + +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Select menu entry. +% +% ( new_entry ) ==> ( ) +% +/xmenu.select { + dup 0 lt { xmenu .xm_list get length add } if + dup xmenu .xm_list get length ge { xmenu .xm_list get length sub } if + + xmenu .xm_current get over xmenu .xm_current rot put + xmenu.viewentry + xmenu.viewentry +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Panel/xmenu helper function. +% +% ( ) => ( ) +% +/pmenu.panel.update { + panel.text.moveto + + xmenu .xm_panel_x currentpoint pop xmenu.hspace sub put + xmenu .xm_x xmenu .xm_panel_x get put + + pmenu.update +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Panel/xmenu helper function. +% +% ( ) => ( width ) +% +/pmenu.width { + % Use this instead of the line below and remove the actRedrawPanel + % things if you want fixed size panel entries. + + % xmenu .xm_panel_width get xmenu.hspace 2 mul sub + + xmenu .xm_list get xmenu .xm_current get get strsize pop +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Panel/xmenu helper function. +% +% ( ) => ( ) +% +/pmenu.update { + xmenu .xm_panel_x get xmenu.hspace add panel.text.y moveto + xmenu .xm_panel_width get xmenu.hspace sub xmenu .xm_panel_height get + panel.bg setcolor fillrect + + panel.normal setcolor + panel.font setfont + xmenu .xm_panel_x get xmenu.hspace add + panel.text.y + moveto + xmenu .xm_list get xmenu .xm_current get get show +} def + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% Panel/xmenu helper function. +% +% ( ) => ( ) +% +/pmenu.init { + xmenu.sizes + + xmenu .xm_y panel.text.y 1 sub xmenu.height sub put + xmenu .xm_panel_width xmenu.width put + xmenu .xm_panel_height fontheight put +} def + + @@ -0,0 +1,21 @@ +#! /bin/sh + +what=$1 +theme=$2 + +[ "$theme" ] || theme=SuSE + +if [ ! "$what" -o ! -x ~/gfxtest/tst.$what ] ; then + echo "usage: tst what" + exit +fi + +make BINDIR=../../ -C themes/$theme || exit + +file=themes/$theme/boot/message +[ "$what" = install -o "$what" = install3 -o "$what" = cdrom ] && file=themes/$theme/install/bootlogo + +cp $file ~/gfxtest/bootlogo +cd ~/gfxtest/ +./tst.$what + diff --git a/utf8/UTF-8-demo.txt b/utf8/UTF-8-demo.txt new file mode 100644 index 0000000..bfb9ec8 --- /dev/null +++ b/utf8/UTF-8-demo.txt @@ -0,0 +1,212 @@ + +UTF-8 encoded sample plain-text file +‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ + +Markus Kuhn [ˈmaʳkʊs kuːn] <http://www.cl.cam.ac.uk/~mgk25/> — 2002-07-25 + + +The ASCII compatible UTF-8 encoding used in this plain-text file +is defined in Unicode, ISO 10646-1, and RFC 2279. + + +Using Unicode/UTF-8, you can write in emails and source code things such as + +Mathematics and sciences: + + ∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ⎧⎡⎛┌─────┐⎞⎤⎫ + ⎪⎢⎜│a²+b³ ⎟⎥⎪ + ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β), ⎪⎢⎜│───── ⎟⎥⎪ + ⎪⎢⎜⎷ c₈ ⎟⎥⎪ + ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⎨⎢⎜ ⎟⎥⎬ + ⎪⎢⎜ ∞ ⎟⎥⎪ + ⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (⟦A⟧ ⇔ ⟪B⟫), ⎪⎢⎜ ⎲ ⎟⎥⎪ + ⎪⎢⎜ ⎳aⁱ-bⁱ⎟⎥⎪ + 2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm ⎩⎣⎝i=1 ⎠⎦⎭ + +Linguistics and dictionaries: + + ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn + Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ] + +APL: + + ((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈ + +Nicer typography in plain text files: + + ╔══════════════════════════════════════════╗ + ║ ║ + ║ • ‘single’ and “double” quotes ║ + ║ ║ + ║ • Curly apostrophes: “We’ve been here” ║ + ║ ║ + ║ • Latin-1 apostrophe and accents: '´` ║ + ║ ║ + ║ • ‚deutsche‘ „Anführungszeichen“ ║ + ║ ║ + ║ • †, ‡, ‰, •, 3–4, —, −5/+5, ™, … ║ + ║ ║ + ║ • ASCII safety test: 1lI|, 0OD, 8B ║ + ║ ╭─────────╮ ║ + ║ • the euro symbol: │ 14.95 € │ ║ + ║ ╰─────────╯ ║ + ╚══════════════════════════════════════════╝ + +Combining characters: + + STARGΛ̊TE SG-1, a = v̇ = r̈, a⃑ ⊥ b⃑ + +Greek (in Polytonic): + + The Greek anthem: + + Σὲ γνωρίζω ἀπὸ τὴν κόψη + τοῦ σπαθιοῦ τὴν τρομερή, + σὲ γνωρίζω ἀπὸ τὴν ὄψη + ποὺ μὲ βία μετράει τὴ γῆ. + + ᾿Απ᾿ τὰ κόκκαλα βγαλμένη + τῶν ῾Ελλήνων τὰ ἱερά + καὶ σὰν πρῶτα ἀνδρειωμένη + χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά! + + From a speech of Demosthenes in the 4th century BC: + + Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι, + ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς + λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ + τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿ + εἰς τοῦτο προήκοντα, ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ + πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν + οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι, + οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν + ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον + τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι + γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν + προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους + σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ + τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ + τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς + τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον. + + Δημοσθένους, Γ´ ᾿Ολυνθιακὸς + +Georgian: + + From a Unicode conference invitation: + + გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო + კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს, + ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს + ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი, + ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება + ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში, + ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში. + +Russian: + + From a Unicode conference invitation: + + Зарегистрируйтесь сейчас на Десятую Международную Конференцию по + Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии. + Конференция соберет широкий круг экспертов по вопросам глобального + Интернета и Unicode, локализации и интернационализации, воплощению и + применению Unicode в различных операционных системах и программных + приложениях, шрифтах, верстке и многоязычных компьютерных системах. + +Thai (UCS Level 2): + + Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese + classic 'San Gua'): + + [----------------------------|------------------------] + ๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่ + สิบสองกษัตริย์ก่อนหน้าแลถัดไป สององค์ไซร้โง่เขลาเบาปัญญา + ทรงนับถือขันทีเป็นที่พึ่ง บ้านเมืองจึงวิปริตเป็นนักหนา + โฮจิ๋นเรียกทัพทั่วหัวเมืองมา หมายจะฆ่ามดชั่วตัวสำคัญ + เหมือนขับไสไล่เสือจากเคหา รับหมาป่าเข้ามาเลยอาสัญ + ฝ่ายอ้องอุ้นยุแยกให้แตกกัน ใช้สาวนั้นเป็นชนวนชื่นชวนใจ + พลันลิฉุยกุยกีกลับก่อเหตุ ช่างอาเพศจริงหนาฟ้าร้องไห้ + ต้องรบราฆ่าฟันจนบรรลัย ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ + + (The above is a two-column text. If combining characters are handled + correctly, the lines of the second column should be aligned with the + | character above.) + +Ethiopian: + + Proverbs in the Amharic language: + + ሰማይ አይታረስ ንጉሥ አይከሰስ። + ብላ ካለኝ እንደአባቴ በቆመጠኝ። + ጌጥ ያለቤቱ ቁምጥና ነው። + ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው። + የአፍ ወለምታ በቅቤ አይታሽም። + አይጥ በበላ ዳዋ ተመታ። + ሲተረጉሙ ይደረግሙ። + ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል። + ድር ቢያብር አንበሳ ያስር። + ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም። + እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም። + የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ። + ሥራ ከመፍታት ልጄን ላፋታት። + ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል። + የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ። + ተንጋሎ ቢተፉ ተመልሶ ባፉ። + ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው። + እግርህን በፍራሽህ ልክ ዘርጋ። + +Runes: + + ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ + + (Old English, which transcribed into Latin reads 'He cwaeth that he + bude thaem lande northweardum with tha Westsae.' and means 'He said + that he lived in the northern land near the Western Sea.') + +Braille: + + ⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌ + + ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞ + ⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎ + ⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂ + ⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙ + ⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑ + ⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲ + + ⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ + + ⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹ + ⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞ + ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕ + ⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹ + ⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎ + ⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎ + ⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳ + ⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞ + ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ + + (The first couple of paragraphs of "A Christmas Carol" by Dickens) + +Compact font selection example text: + + ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789 + abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ + –—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд + ∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა + +Greetings in various languages: + + Hello world, Καλημέρα κόσμε, コンニチハ + +Box drawing alignment tests: █ + ▉ + ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳ + ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳ + ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳ + ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳ + ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎ + ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏ + ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█ + ▝▀▘▙▄▟ diff --git a/utf8/font b/utf8/font new file mode 100644 index 0000000..9645f71 --- /dev/null +++ b/utf8/font @@ -0,0 +1 @@ +./getx11font -v -l 18 -p 2,4 -a 0x20-0xff -a 0x20ac --add-text utf8/utf_sample -f `cat utf8/uf1` -f `cat utf8/uf2` themes/SuSE/16x16.font diff --git a/utf8/font2 b/utf8/font2 new file mode 100644 index 0000000..9cdd46d --- /dev/null +++ b/utf8/font2 @@ -0,0 +1 @@ +./getx11font -v -l 18 -p 2,4 -c latin1 -c latin2 -a 0x20ac -t utf8/utf_sample -f `cat utf8/uf1` -f `cat utf8/uf2` themes/SuSE/16x16.font diff --git a/utf8/font3 b/utf8/font3 new file mode 100644 index 0000000..1b67453 --- /dev/null +++ b/utf8/font3 @@ -0,0 +1 @@ +./getx11font -v -l 18 -p 2,4 -c ISO-8859-15 -c ISO-8859-2 -t utf8/utf_sample -f `cat utf8/uf1` -f `cat utf8/uf2` 16x16.font diff --git a/utf8/font4 b/utf8/font4 new file mode 100644 index 0000000..3ace17d --- /dev/null +++ b/utf8/font4 @@ -0,0 +1 @@ +./getx11font -v -l 18 -p 2,4 -c koi8-r -c ISO-8859-15 -c ISO-8859-2 -t utf8/utf_sample -f `cat utf8/uf1` -f `cat utf8/uf2` 16x16.font diff --git a/utf8/font5 b/utf8/font5 new file mode 100644 index 0000000..e7fb252 --- /dev/null +++ b/utf8/font5 @@ -0,0 +1 @@ +./getx11font -v -l 18 -p 2,4 -c koi8-r -c ISO-8859-15 -c ISO-8859-2 -t utf8/utf_sample -t themes/SuSE/install/log -f `cat utf8/uf1` -f `cat utf8/uf2` 16x16.font diff --git a/utf8/uf1 b/utf8/uf1 new file mode 100644 index 0000000..f194bb3 --- /dev/null +++ b/utf8/uf1 @@ -0,0 +1 @@ +-efont-fixed-medium-r-normal--16-160-75-75-c-80-iso10646-1 diff --git a/utf8/uf2 b/utf8/uf2 new file mode 100644 index 0000000..c802b78 --- /dev/null +++ b/utf8/uf2 @@ -0,0 +1 @@ +-efont-fixed-medium-r-normal--16-160-75-75-c-160-iso10646-1 diff --git a/utf8/uf3 b/utf8/uf3 new file mode 100644 index 0000000..a32ebc7 --- /dev/null +++ b/utf8/uf3 @@ -0,0 +1 @@ +-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso10646-1 diff --git a/utf8/utf_sample b/utf8/utf_sample new file mode 100644 index 0000000..aa411f5 --- /dev/null +++ b/utf8/utf_sample @@ -0,0 +1 @@ +ᚻᛖ睡不足の |