Scenergy #02
31 декабря 1999 |
|
Coding - the libraries of programming on the Spectrum.
About the libraries. 0. Instead of joining During the time of writing this article three times changed its name and content. First I just wanted to write a little note its interface library ICL, I was going to publish. But when writing the article was that there is Two issues are of direct concerning this topic. I finished the chapters on freely available libraries and Principles of writing konfigurabelnogo code. But by the end of this work found that, firstly, there are several reasons on which I currently can not accurately to say: I will publish the ICL or not. A Secondly, it turned out that what I wanted post as an example to the article about packaging animations gradually takes form a complete library, with just This is who I would like to see a good library. So we had to once again all change, and as a result of the description ZXA library and a Memory Management Library were a separate article, but this article was entirely devoted to my reflections on the theme "The ability to create a full-fledged Libraries in Spectrum:) I beg you not to perceive all set out below as my attempt to impose on you their point of view on how to write code. This simply an attempt to share their experiences, accumulated over the years on several platforms. 1. Redistributable libraries At that moment, when I started writing this article, the situation with assemblers on Speccy was just depressing. Among coders were distributed about a dozen assemblers almost completely incompatible with each another. And not at the level of incompatible format source code (that would be decided simple converters), and at the level of the Chief - syntax! If a set of mnemonics Z80 assembler itself was, thank God, still the same (the "distinguished" only STORM), then even the slightest expansion already had their own each assembler. Here, felt, the authors simply assemblers competed in the original - who is from They come up with more features, which are not in other assemblers. And thus, sometimes forgetting what matters most - on the implementation of those features, that have already been made in other assemblers. For example, half the assembler does not supported by brackets in expressions. I interesting - and the authors have tried at least once write more or less complex expression without brackets? Apparently not. But, nevertheless, support brackets in the expressions was (if take only modern assemblers) are still in TASM v2.0 already, 1993 release! Or allocation of senior and junior byte words in the same terms. I know of at least 3 assembly in which a function there, but its syntax is different in all three! And, most importantly, the authors of all assemblers as scored a big bolt on application to their offspring at least some something more important bloat on opportunities of the compiler. In the end, the speed compilation, though important, but far not the most important criterion in assessing the quality compiler. Often when working on large project suddenly appears that the encoder simply not able to control those volume source, with whom he have to work. Already no speed compilation will not help if the person physically unable to forgetting half of them all the details in your own code. In this case, often the project may simply die. It can only help further tools provided by compiler and designed to facilitate the organization of work on a large project. On the part of bloat in the compiler The only bright spot so far there was only TASM v4.12 by RST7/CBS. Only it gets a coder in his own hands such powerful tools such as macros and conditional compilation. A plus to this tag unlimited length and the normal mechanism work with the main file'ami, but bells and whistles in editor, such as keyboard macros - All this makes the undisputed leader in TASM Spectrum number of assemblers. Course and it is not all smooth - no nested conditional compilation, and a small table tags create some inconveniences, but at least in this assembly can create and manage large projects. Unfortunately, most of the Spectrum coder does not understand the importance of these things. They are much more important than speed compilation, or, for example, support mnogotekstovosti. Therefore, our glorious coders sit ALASM'e, STORM'e or XAS'e. But now the situation is, fortunately, has changed the better. Appeared acceptable to Most compromise - ALASM v4.2. This version, modified KVA / E-Mage has support for almost all extensions TASM'a - macros, conditional compilation, parentheses in expressions. And that is very important - the syntax of these extensions compatible with TASM'om! Of course, as always the case, compatibility is not complete, but quite sufficient to ensure the portability of the source between TASM'om and ALASM'om. True, because of differences in a set of these two assemblers to ensure portability will comply with a set of rules. For example, in TASM'e not supported by binary numbers, no nested conditional compilation, no side ALASM'a functions used in expressions No construction DUP-EDUP. On the other hand in ALASM'e not function DISPLAY, and local labels and work with the main file'ami done wrong. But this is a trifle on Compared with the fact that now we have ability to write code using normal instruments, and this code can use at least half All Spectrum coders (mostly by ALASM'a). Now you need to explain - why I actually started the whole conversation. Case that on the Speccy, both on the platform, virtually no one very good thing, widespread in other platforms (especially in an environment of UNIX-like OS). I'm talking about the phenomenon as a free distributed in source code libraries. Remember how often have you faced with similar libraries? Most likely, not very often, but most - so and never. More precisely, they faced with them, but in a slightly different form - in as published in some magazine article, which describes a particular set of procedures. Personally, I've seen of all time Only five pieces of such libraries and some more collections of procedures that can be stretch to call libraries. As these collections can bring well-known Packages SuperCode. As the same example complete library can be reduced Hrust Library Dima Pyankov. Some people might ask like: "Why do we all? We're all write no worse or even better! "On the one side is right. But on the other hand just because of lack of practice issue and, more importantly, the use of such libraries, we can observe a huge number of examples of good by nature software, ruined just because of the fact that in some areas the author turned out to be non-specialist. For examples not far to seek - anyone remember a lot of programs that he would use, if not ... Then you can put a bunch of things - the poor to an inability to interface eerie way of working with a disk, wrong Work with a joystick and mouse, no support or malfunctions with expanded memory and more. Remember? Now think - if author of such a program did not invent bike, but just be prepared to use library, which would implement all necessary function in any area. And would do it at a high level, is: - If a library interface, it is would provide an easy interface creation easy to use and contains all the necessary interface elements. - If this library works with the disk, then She'd worked well with all kinds of disk drives and the right to processed all the disk errors. - If this library works with a joystick and mouse, it would provide job with all the common schemes, had would allow both avtodetekta and manual settings, etc. - If this library works with memory, it would ensure correct operation with all common extensions Memory avtodetekt type and amount of memory and other such things. In this case the author: 1. Would not have to puzzle over, how to do this or that thing so that it works if not all, of the the overwhelming majority. 2. Would not have to spend time to think, write and debug it, that even before he invented, written and debugged more than once, often it worked better than him. And among other things its programs will look and work better with a much lower cost of time and effort. For those who read the writing above, thought something like: "nafig me this is necessary, still deal with foreign-source! I had better write everything! "I want to say that: 1. You do not fully imagine that volume of work that needs to be done to realize some things. In addition Think about it: "I possess a sufficient set of knowledge, expertise and time to write it yourself? ". Here are a few Examples: Suppose you write a graphic editor for the PC (or AMiGA, it does not matter). Every editor has to have a normal support pile of graphic formats. So Here, take you to write support formats such as JPEG or PNG? Or all also take advantage of ready, debugged, free and delivered in source code libraries and jpeglib pnglib? To to give you a little bit of information will give statistics on the volume of initial texts of these libraries: jpeglib: 57 files, 816541 bytes pnglib: 21 files, 550314 bytes In my comments here are unnecessary. Or another example (for the Speccy, so it was clearer) - whether you take you to write support any devaysa, which you do not, and you in the eye never seen? And even so it is right work? Or, will you write For example, a compressor, not being specialists in the field of data compression? Are you sure that your compressor will compress the data better than Hrust? Or do you still take free, supplied in source code and having a good description of the library Hrust Library? 2. You do not fully understand the essence of that is embedded in the concept of "library". - A good library is written by a man which is very well versed in the area for which it creates a library. So the opportunities and quality of the code, included in this library will be certainly better than what they can write most of those who deal in this matters worse, than the author of the library. - A good library is written on the basis of considerations that the code will be used other people. Ie a good library - it not just a set of procedures. That's good annotated code and a well-designed interface part. Library functions should provide, if not all, then, At least most of what set functions required of this type code. Ie if someone sat down and wrote for a few protsedurok, and then decided to publish them - it will not be a library, as just another set of procedures. - A good library has a detailed description of its capabilities, principles of each of the interface functions, all necessary data structures, etc. Also, as a rule, with a good library delivered several programs - examples use. - Code of good library is configurable in wide range. This will be discussed More details in the next section. - The interface part of a good library understand the person does not go into detail principles of operation of the library. This, for example, means that all identifiers (Label), which will use an encoder to work with this library should be readable for everyone, not just for the author's library. For example, in a good library should not be the procedures and / or variables with names such as: VXSTPD, PROC1, ZXCVBNM etc. Any normal assembler should be support for labels of any length (like TASM and ALASM), so do not torment a man asking him riddles such as "what does the label CRRLSTB? ". It is much better if the label will have the name CREATE_ROLL_SPRITES_TABLE, which is essentially the same, only the second option will be immediately understandable to all, then as the meaning of the first version tags anyone good to smash his head. Besides that identifiers should be understandable - they should also be well systematized, so that people with first look at the name tags was a general idea of what it for the label. Here is an example set of rules by which constructed identifiers in my library ICL: - All the names of front-end processes (through that the program works with the library) begin with the prefix ICL_, to the code program immediately visible to all calls library functions. Example: ICL_OPEN_WINDOW - Identifiers of fields of data structures formed as follows: [Reduction in the name of the structure]. [Field Name] Example: the data structure for point menu (Menu Item) are as follows: MI.X - X coordinate of the menu item MI.FLAGS - flags menu MI.HANDLER - procedure handler Example of use: LD A, (IX + MI.X) - Identifiers masks to isolate bits in flag bytes are prefixed with '_' before the name. Example: The flags in the flag byte item menu (Menu Item Flags): _MIF_ACTIVE - Menu item is active _MIF_SELECTED - Menu item is selected Example of use: LD A, (IX + MI.FLAGS) AND _MIF_ACTIVE JR Z, INACTIVE_MENU_ITEM - IDs are numbers of bits for flags in flag bytes are prefixed with 'B_'. Example: The flags in the flag byte item menu (Menu Item Flags): B_MIF_ACTIVE - menu item is active B_MIF_SELECTED - menu item is selected Example of use: BIT B_MIF_ACTIVE, (IX + MI.FLAGS) JR Z, INACTIVE_MENU_ITEM I'm not saying that these rules are ideal, I brought them only as an illustration. The important thing is that if all the identifiers in library built on one principle - it will be much easier to work. As an example, the library, in many respects corresponding to these rules, I can give ZXA library. It's not because I want to own self praise, but because I specifically wrote it with the expectation to show how to create a good library on Speccy. And one of the most important moments in it is its complete konfigurabelnost. That's about it, we'll talk further. 2. Principles of writing konfigurabelnogo code. As usually arrives Spectrum coder if he needs, having a set of procedures change their feature set? Ie to example, if he has a library create an interface and it needs to be taken from it only a part. What he will do in this case? I do think that most answer something like "get into the code and will understand "or" leave as is " or "spit on it and write it all himself." A reason for this is the only one - as Typically, Spectrum coders write nekonfigurabelny code! Ie act on the principle of "every program I write from scratch." Or trying to use a portion of the previously written code, faced with the challenge that it is easier to write it all over again than understand "what I wrote and there is how it works. "Indeed, as Typically, hand to view the code, even half-year-old is very difficult remember - that it does, for example, mnemonic BIT 3, (IX +7)? I mean, Of course, what is that gets the data from it means? ":) Naturally this is not always, though often enough. And you have to spit on all writing all the code from scratch, essentially making already done the work a second time. But back to konfigurabelnosti code. What does this term mean? This is an opportunity changes in the functioning of the code without editing. I stress again - NO edit it! Ie to remove some of the code or for to change some parameters of code itself does not need to touch it! And this in turn turn means that in order to use this code in your programs (And hence to adjust it to fit your needs) it is not necessary to delve into the code and thoroughly study the principles of its operation. Enough to know 2 things: 1) A set of "interface" procedures. These are procedures through which work. 2) A set of configuration variables for code settings for a specific task. How could create such a code? Using high-level languages to do it fairly easily because They, inter alia provide tools for writing such a code and, moreover, there original text have little to do with how specifically will look like executable code. Writing konfigurabelnogo assembly code more complex, but is also quite possible. Just here we have the very act the role of the compiler and another for writing consider how the code should look like in different configurations. True Spectrum assemblers seriously inferior to professional compiler compile a set of guidelines, but even so, that is, writing code konfigurabelny quite real. Even fairly simple although for some people it can be a bit unusual. Here are a few moments, considering that when writing code, you can achieve it konfigurabelnosti: 1. Any thing you can afford change should be allowed to change. If this parameter - its value is not specified in code, and EQU. Accordingly, all values that depend on this parameter should be given not constant, and expression. 2. The code is written on the basis of considerations that any part of it may subsequently be changed. This is especially true of structures data consisting of several fields. In High-level language compilers that item sold by itself because generate real executable code only occurs at compile time, and hence all the indices (bias) fields in data structures, too, are calculated compiler itself. When working with assembly language on the job assignment of indices of fields of data structures have to travel by hand. If these Indexes are defined in the program clearly - then changes in the composition and / or field sizes in structure of all indexes "float" and their have to recalculate again. Allow Let it be, especially if you plan control code generation from the outside. Therefore, indexes of all fields of data structures used in the code is also necessary ask a EQU so that in case change the set of fields and / or their size not become necessary to manually edit code. Also, this approach implies a rejection from hand-optimizing the code conversion between the fields of data structures in their processing. For example, we have the following Structure: STRUCTURE DEFB 0; FIELD 1 DEFW 0; FIELD 2 DEFW 0; FIELD 3 If there is no certainty that all possible configurations of the code, this structure remain unchanged, then the code can not be use constructions like this: LD HL, STRUCTURE LD A, (HL); GET FIELD 1 INC HL LD E, (HL); GET FIELD 2 INC HL LD D, (HL) You also can not change the INC HL for INC L, if there is no certainty that the transition through block border (256 bytes) will not be in ALL possible configurations of the code. If the use of such structures pochemulibo necessary - these moments should be separately specify (for example, put in this area code comment marked, under what conditions this code section will work properly). 3. The code must be built as a set independent or loosely coupled components. Under the weak link, I mean that one component interacts with other as well as external code interacts with these components, ie only through interface procedure (which can be at be easily emulated). Then the absence of any component or not impact on other components or have to write alternative code snippets that work without removing components. 4. Because almost any code requires its work under the allocation of sites of memory private use - when creating a code can not do without the mechanism of selection memory. Oh, how this can be done - Read my article on Memory Management Library. If you carefully read what was written above - you realize that the full to realize all this can only using conditional compilation. Only in this way can be realized by substitution of code segments in compile time. Macros are also very much needed for konfigurabelnosti code - they can be used to implement many desired functions. Accordingly, taking into account all written above, one might say - to write this code at the moment is only possible for two assemblers: TASM v4.12 and ALASM v4.2. But as I said above - total of these assemblers will cover about half of all Spectrum coders, and hence such Libraries will find their user. 3. Spread Highlights of that description that you just read, I have already discussed with some quite famous people on the Speccy. And to his surprise, he heard that they all hold the same opinion: MiniSoft avec NRJ / ACL The question of whether it would be distributed Doors2000 in the source code. > Doors will apply only how to compile > Module and not the other way! > I would not like that would be the pioneers of sorts in it, and tinkering > Started to produce glitches. D-Man/EI The question of how to relate to the idea of EI distribution of sources (for example, Library ICL). > About the ICL, I do not even know. Extending it you ever had > Lot of the same light prog different lamer, who broke > Write a shell. > For example, we do not want to release source code Napalm'a precisely > Therefore, since After publication, we generate a lot of similar > Boring dem. All this should not a coder, since self-respecting > Encoder will never use another source. Ie The authors are afraid that their code will be used by people who themselves are not under By writing the same thing and that just "Steal" their code, making the poor quality program and spit on all copyright'y. Yes, this danger is certainly there. But There are several points that can not be forget. First, almost any library sufficiently large. Ie the amount of its initial texts of, say 100k, and even more. Frankly, that person especially unprepared (ie, Lameroo) will simply be extremely difficult for any way "perekovyryat" code of the library so as to significantly change it and while maintaining operational. And it is unlikely Is lamer deal with that. If Right - then your code is in many ways helped its development and this will all just benefits - perhaps in the future he would write a lot of cool programs. Remember - all We begin with breaking and studying other people's code, there is nothing wrong with someone begins with a study of written sources professionals. Secondly, all somehow forget that that except lamer, which must be kept in cage until one does not get anything worthwhile, there are also more experienced people. AND what self-respecting encoder must write myself - just a controversial opinion. In the beginning of this article, I have already cited a number of examples where even an experienced coder was make better use of existing code, rather than write something of my own. Because if it "Something special" will be worse than what he could use in their program, then would be worse, end users This program itself, ie ourselves. The simplest example: the well-known Screen Optimizer. It is very necessary and useful thing but for this interface Personally, I would like to tear author hands (shutka!). Or demos with multiloader'ami that do not work on half of the drives? Or games that You can not run because of an incorrect Poll Kempston mouse? Remember, after all these things were just written by the authors of programs! And, as it turned out - poorly written. A hit from this we all are. Does not it would be better if they all used instead ready-made, well-written and debugged Library? And now with regard to dem. Here, of course every everything he wrote as Now demos in most cases are not written just so, and to participate in the demo compo at any party. But, for example, I personally would not have refused to take advantage of some procedures from the same Napalm'a in its Deme. And not because of the fact that I did not I write the same thing. No, I do not against the use by some super fast inner loop'om texturemapper'a or procedure for sorting polygons simply because, if my procedure will be run more slowly - this, at the end all, affected viewers. Admittedly this is already no library, but also concerns the proliferation of sources. And finally, let's look at other platform. The practice of creating libraries, distributed in source code there is quite rampant. Moreover - as Typically, such libraries are also cross-platform, ie collected and work on multiple platforms, in an environment Many compilers and OS. Examples result in a mass call at least previously I have mentioned jpeglib and pnglib, as well as library work. zip archives - zlib. In addition, one can not forget such things as OpenPTC (multi-platform library to unify the work of video memory) and Crystal Space (powerful 3D engine with lots of additional tools for creating 3D games virtually all platforms). All of them, Like many other libraries, free distributed in source code and In addition, they are allowed to commercial software products. Their presence helps many people to create quality programs, and as a result will only benefit! What is the Speccy worse? Why do not we start a similar practice - I am sure that all of us are too will only benefit!
Other articles:
Similar articles:
В этот день... 21 November